LearnNewsExamplesServices
Frontmatter
id16530
titleThe Data Sync failure message asserts a credential cause it cannot know
stateClosed
labels
bugai
assignees[]
createdAtAug 5, 2026, 8:50 AM
updatedAtAug 5, 2026, 1:24 PM
githubUrlhttps://github.com/neomjs/neo/issues/16530
authorneo-opus-ada
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 5, 2026, 1:24 PM

The Data Sync failure message asserts a credential cause it cannot know

neo-opus-ada
neo-opus-ada commented on Aug 5, 2026, 8:50 AM

Context

The Data Sync pipeline has been failing for 20 consecutive runs (#16428 alarm). The actual cause is a missing npm package. The operator-visible failure line says:

[DataSync] stage "GitHub Workflow corpus" failed under declared credential scope `reader`.
If this is an authentication failure, the stage requires a scope that grants it — never an
ambient credential.

The real error, 550 log lines earlier:

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'chromadb'
  imported from /home/runner/work/neo/neo/ai/services/knowledge-base/ChromaManager.mjs

Not an authentication failure. Not a credential-scope problem. A packaging one.

The Problem

buildScripts/dataSyncPipeline.mjs:547 prepends the credential-scope framing to every stage failure, unconditionally, before knowing anything about the failure's class:

error.message = `[DataSync] stage "${label}" failed under declared credential scope ` +
    `\`${tokenScope}\`. If this is an authentication failure, the stage requires a scope ` +
    `that grants it — never an ambient credential.\n${error.message}`;

Its own comment states the problem it was built to solve — "a bare child failure reads as 'the tool is broken' when the finding is 'this stage was granted none and needs a credential'" — and that reasoning is sound. But the annotation was made unconditional, so it now produces the mirror-image defect: a packaging failure reads as an auth failure.

The If this is an authentication failure hedge is real, and it is not enough. In an operator-visible log tail, the annotation is the last line and the true error has scrolled past. The hedge is only readable by someone who already has the answer.

The annotation knows which scope the stage was granted. It does not know whether the failure had anything to do with credentials — and it is phrased as though it does.

The Architectural Reality

emitStages in buildScripts/dataSyncPipeline.mjs (:531:549). tokenScope is a per-stage declaration; the child's exit is opaque to it. Every failure class — module resolution, ENOENT, a thrown assertion, a genuine 401 — receives the identical credential-framed prefix.

This is a diagnostic that answers a question adjacent to the one the reader is asking. The reader asks "why did this fail?"; the annotation answers "what was this stage entitled to?" Both are true statements; only one is the question.

The Fix

Classify before annotating. The child's error already carries its class:

  • ERR_MODULE_NOT_FOUND / MODULE_NOT_FOUND → a dependency/packaging failure. Say so, and do not lead with credentials.
  • ENOENT on the script path → the stage's entrypoint is missing.
  • auth-shaped (401, 403, authentication, credentials, permission, Bad credentials) → the existing credential framing is correct and should stay.
  • anything unrecognized → say the class is unrecognized and state the scope as context, never as a diagnosis.

The scope annotation stays in all four cases — it is genuinely useful context. What changes is that it stops leading with a hypothesis it cannot support, and the last-line-in-the-tail slot goes to the class that was actually observed.

Deliberately preserving the original design constraint: no per-stage requiresCredential flag. The classification is derived from the observed error, so it cannot drift from a hand-maintained declaration — the same property the current annotation was built for.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
emitStages failure message this ticket leads with the observed failure class; scope stated as context unrecognized class ⇒ says "unrecognized", never asserts a cause in-source spec per class
tokenScope declaration unchanged still the only scope authority no per-stage flag added
exit codes / deferral behaviour unchanged publishGeneratedProgressOnFailure path untouched existing pipeline specs green

Decision Record impact

none. Message construction inside one build script.

Acceptance Criteria

  • An ERR_MODULE_NOT_FOUND child failure produces a message naming a dependency/packaging failure, and does not lead with credential framing. Red witness: today's chromadb error.
  • A genuine auth-shaped failure still produces the existing credential guidance — the case the annotation was built for must not regress.
  • An unrecognized failure class states that it is unrecognized rather than asserting any cause.
  • The declared tokenScope still appears in every case; this narrows the claim, it does not remove the context.
  • No per-stage requiresCredential flag is introduced — classification stays derived from the observed error.

Out of Scope

  • The chromadb failure itself — that is #16495 / PR #16496, which fixes the import chain.
  • The [skip ci] / ruleset interaction — separate, and ruleset config is operator-owned.
  • Log verbosity or ordering elsewhere in the pipeline.

Avoided Traps

  • Deleting the annotation. It solves a real problem the comment documents; the defect is that it is unconditional, not that it exists.
  • A per-stage requiresCredential flag. Explicitly rejected in the original design for a good reason: a second hand-maintained declaration beside tokenScope, free to drift. Classification from the observed error keeps that property.
  • Treating the hedge as sufficient. "If this is an authentication failure" is technically honest and operationally useless when it is the last line a reader sees.

Related

  • #16428 — the standing alarm this misdirected diagnosis on, 20 consecutive failures
  • #16495 / PR #16496 — the actual chromadb cause
  • #16449 — same class from another angle: a diagnostic stating something adjacent to what its reader needs

Live latest-open sweep: latest 20 open issues checked at 2026-08-05T03:40Z; no equivalent found.

Origin Session ID: eeacb603-97f1-4241-9b2f-3a542cab6d2c

Retrieval Hint: query_raw_memories("dataSyncPipeline credential scope annotation misdiagnosis") · failed under declared credential scope

tobiu referenced in commit cdd34c5 - "fix(ci): the Data Sync failure lead states the observed class, not a credential cause it cannot know (#16530) (#16531) on Aug 5, 2026, 1:24 PM
tobiu closed this issue on Aug 5, 2026, 1:24 PM