Skip to content

Known-error/fix config errors are silently dropped at load time instead of failing loudly #344

Description

@rubberduck203

Summary

Config::new swallows errors when converting a raw config entry into its typed model — a ScopeKnownError (or any other model) that fails validation just silently disappears from the loaded config instead of surfacing an error to the user.

// src/shared/config_load.rs:167-171
for raw_config in raw_config {
    if let Ok(value) = raw_config.try_into() {
        this.add_model(value);
    }
}

The Err case is discarded with no logging, no warning, nothing. Found while manually validating #343 (regex captures in known errors), which added a reserved-capture-name validation (src/shared/models/internal/known_error.rs:90, RESERVED_CAPTURE_NAMES = ["working_dir", "captures"]) and eager fix-template validation — both of which return an Err on invalid config, but that Err never reaches the user.

Reproduction (MVCE)

mkdir -p /tmp/scope-silent-drop/.scope
cat > /tmp/scope-silent-drop/.scope/known-error.yaml <<'YAML'
apiVersion: scope.github.com/v1alpha
kind: ScopeKnownError
metadata:
  name: bad-reserved
  description: uses a reserved capture group name
spec:
  pattern: "boom: (?<captures>.*)"
  help: "should never load"
YAML

cd /tmp/scope-silent-drop
scope-intercept -- bash -c 'echo "boom: xyz"; exit 1'

Expected: the tool refuses to start, or at minimum logs an ERROR/WARN naming the bad file and the reserved-name violation.

Actual: the command runs clean and prints No known errors found — as if the ScopeKnownError file didn't exist at all. There is no indication anywhere that a config file was rejected, why, or which file it was. A user who typos a capture group name (or ships a fix with a broken minijinja template) gets no signal that their known-error config isn't doing anything.

Same silent-drop happens for a broken fix template, e.g.:

spec:
  pattern: "boom: (.*)"
  fix:
    commands:
      - "echo {{ unclosed"

Suggested fix

At minimum, log the conversion error (with the source file path) at WARN or ERROR in the if let Ok(...) / else branch in Config::new. Arguably this should be a hard failure (non-zero exit) since a silently-ignored known error or fix is a correctness footgun, not a degraded-but-working state.

Where this lives

  • src/shared/config_load.rs:167-171 — the swallow site
  • src/shared/models/internal/known_error.rs:90 — reserved capture name rejection (one of the Err cases being swallowed)
  • src/shared/models/internal/fix.rs — eager fix-template validation (another Err case being swallowed)

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions