Skip to content

fix(automation): skip update on research exception so repos retry - #70

Open
detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fix-automation-skip-update-on-research-exception-s-687014
Open

detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fix-automation-skip-update-on-research-exception-s-687014

Conversation

@detail-app

@detail-app detail-app Bot commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

Detail bug report: View on Detail

Summary

  • Context: The researchRepositoryDescriptions automation task (commit 3587d45, reworked in 6366007) populates the useDescription / impactDescription fields on the Repository GraphQL type so recruiters see why contributing to a repo is impressive.
  • Bug: When a research call throws a non-retryable API error (e.g. OpenRouter 402 payment required, 403 model-access/key revoked, 400 model renamed, 401 auth failure) or a sustained outage that survives the SDK's 2-retry budget, the task swallows the exception but still stamps descriptionsFetchedAt and calls prisma.repository.update with null descriptions. The row is then permanently excluded by where: { descriptionsFetchedAt: null } on every future run.
  • Actual vs. expected: On an exception, the repository should be skipped so it is retried next run (like the sibling generatePrDescriptions task does for errors). Instead descriptionsFetchedAt is persisted and the repository silently loses both recruiter-facing descriptions forever with no recovery path.
  • Impact: The useDescription/impactDescription fields are nullable enhancement fields; the repository's name, url, logoUrl, projects, and projectCount remain visible — the feature degrades to its pre-3587d45 state for affected rows, which is not catastrophic but is permanent and silent.

Code with Bug

src/automation/tasks/researchRepositoryDescriptions.ts:

  for (const repository of repositories) {
    // Set unconditionally (even if the AI returns nothing usable below), so we don't
    // keep re-running (and re-billing for) a repository the AI can't describe.
    const data: { useDescription?: string, impactDescription?: string, descriptionsFetchedAt: Date } = {
      descriptionsFetchedAt: new Date(), // <-- BUG 🔴 set even when research() throws, preventing retries
    };

    if (!repository.useDescription) {
      try {
        const useDescription = await research(openRouter, usePrompt(repository.name, repository.url));
        if (useDescription) data.useDescription = useDescription;
      } catch (ex) {
        DEBUG(`Failed to research use description for repository ${repository.id}:`, ex); // <-- BUG 🔴 error swallowed but task still updates row
      }
    }

    if (!repository.impactDescription) {
      try {
        const impactDescription = await research(openRouter, impactPrompt(repository.name, repository.url));
        if (impactDescription) data.impactDescription = impactDescription;
      } catch (ex) {
        DEBUG(`Failed to research impact description for repository ${repository.id}:`, ex); // <-- BUG 🔴 error swallowed but task still updates row
      }
    }

    await prisma.repository.update({ where: { id: repository.id }, data }); // <-- BUG 🔴 runs even if both research() calls threw
  }

The selection query that prevents recovery:

  const repositories = await prisma.repository.findMany({
    where: { descriptionsFetchedAt: null }, // once stamped, this repo is never selected again
    take: 5,
  });

Explanation

  • The task always sets descriptionsFetchedAt and always executes prisma.repository.update, even if research() fails via exception.
  • Because selection is where: { descriptionsFetchedAt: null }, a repo that hit an exception becomes permanently ineligible for future runs.
  • This conflates two cases:
    • Soft-null (AI call succeeded but returned nothing usable): intentionally stamp to avoid re-billing.
    • Exception (auth/credits/model access/outage): should not stamp so it can retry next run.

Codebase Inconsistency

src/automation/tasks/generatePrDescriptions.ts handles these cases differently: it stamps inside the try (soft-null) but leaves prDescriptionFetchedAt unset in the catch (exception) so the job retries on the next run. researchRepositoryDescriptions does not.

Recommended Fix

Stamp on soft-null, but skip updating the repository on any exception (leave descriptionsFetchedAt unset) so it will be retried next run, matching the pattern in generatePrDescriptions.

History

This bug was introduced in commit 6366007. The commit's stated goal ("Add take") was to add a descriptionsFetchedAt timestamp so repositories the AI couldn't describe wouldn't be re-billed on every run; the bug slipped in because, in the same change, the author unconditionally pre-populated descriptionsFetchedAt: new Date() into the update payload and removed the prior if (Object.keys(data).length > 0) guard that had previously skipped the prisma.repository.update call entirely when all research() calls failed — conflating the deliberate soft-null stamping with the exception case the guard had also been silently protecting.


Automatic Fixes PRs can be configured here.

@augmentcode

augmentcode Bot commented Sep 25, 2026

Copy link
Copy Markdown
Contributor
🤖 Augment PR Summary

Summary: This PR fixes repository-description automation so transient or API-level research failures remain retriable.

Changes:

  • Adds a per-repository failed flag around use and impact description research.
  • Skips impact research after a failed use-description request.
  • Skips the database update after any research exception, preserving a null descriptionsFetchedAt.
  • Continues to stamp completed passes, including soft-null model responses, to avoid repeated billing.
  • Preserves successful writes for other repositories in the same batch after an individual failure.
  • Adds offline integration-style tests for exceptions, soft-null results, partial pre-existing data, batch isolation, and retry behavior.
Technical Notes: The behavior now matches generatePrDescriptions: exceptions retry on a future run, whereas completed-but-unproductive AI calls are considered attempted.

🤖 Was this summary useful? React with 👍 or 👎

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. No suggestions at this time.

Comment augment review to trigger a new review at any time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant