{"record":{"id":"1f2741a135a564fe","repo":"gastownhall/beads","slug":"deferred-parents-check-s-w","errorCode":null,"errorMessage":"deferred parents: check %s: %w","messagePattern":"deferred parents: check (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/ready_work.go","lineNumber":86,"sourceCode":"\t\treturn nil, err\n\t}\n\treturn r.descendantsOfFutureDeferredParents(ctx)\n}\n\nfunc (r *issueSQLRepositoryImpl) anyFutureDeferredParent(ctx context.Context) (bool, error) {\n\tfor _, table := range []string{\"issues\", \"wisps\"} {\n\t\tvar probe int\n\t\t//nolint:gosec // G201: table is a hardcoded constant.\n\t\terr := r.runner.QueryRowContext(ctx, fmt.Sprintf(\n\t\t\t`SELECT 1 FROM %s WHERE defer_until IS NOT NULL AND defer_until > UTC_TIMESTAMP() LIMIT 1`,\n\t\t\ttable)).Scan(&probe)\n\t\tswitch {\n\t\tcase err == nil:\n\t\t\treturn true, nil\n\t\tcase errors.Is(err, sql.ErrNoRows), dberrors.IsTableNotExist(err):\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn false, fmt.Errorf(\"deferred parents: check %s: %w\", table, err)\n\t\t}\n\t}\n\treturn false, nil\n}\n\nfunc (r *issueSQLRepositoryImpl) descendantsOfFutureDeferredParents(ctx context.Context) ([]string, error) {\n\tvar childIDs []string\n\tfor _, e := range deferredParentEdges {\n\t\t//nolint:gosec // G201: depTable/issueTable/targetCol are hardcoded.\n\t\tq := fmt.Sprintf(`\n\t\t\tSELECT dep.issue_id\n\t\t\tFROM %s dep\n\t\t\tJOIN %s parent ON parent.id = dep.%s\n\t\t\tWHERE dep.type = 'parent-child'\n\t\t\t  AND parent.defer_until IS NOT NULL\n\t\t\t  AND parent.defer_until > UTC_TIMESTAMP()\n\t\t`, e.depTable, e.issueTable, e.targetCol)\n\t\trows, err := r.runner.QueryContext(ctx, q)","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/ready_work.go#L68-L104","documentation":"Wraps an unexpected error from the deferred-parent existence probe in anyFutureDeferredParent, which checks `issues` then `wisps` for any row with defer_until in the future. ErrNoRows and missing-table errors are tolerated (the probe just moves on); anything else is fatal and wrapped here with the table name. This protects ready work from silently proceeding with an unknown deferred set.","triggerScenarios":"Running the ready-work deferred-parent check when the probe SELECT against `issues` or `wisps` fails with something other than ErrNoRows/TableNotExist — e.g. connection refused, permission denied, or SQL syntax/engine error.","commonSituations":"Revoked DB credentials lacking SELECT on the probed table; server outage mid-check; schema corruption; engine errors like UTC_TIMESTAMP unavailability in odd configurations.","solutions":["Read the wrapped driver error and the probed table name to pinpoint the cause","Fix connectivity/credentials so SELECT on issues/wisps works","Verify table integrity/schema for the probed table","Retry once transient server issues clear"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// check connectivity and SELECT grants before ready-work calls\nif err := db.PingContext(ctx); err != nil { return err }\nvar probe int\nif err := db.QueryRow(\"SELECT 1 FROM issues LIMIT 1\").Scan(&probe); err != nil {\n\treturn fmt.Errorf(\"no SELECT access to issues: %w\", err)\n}","typeGuard":"func isDeferredProbeError(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"deferred parents: check \")\n}","tryCatchPattern":"ready, err := repo.GetReadyWork(ctx, filter)\nif isDeferredProbeError(err) {\n\t// transient server/permission issue: back off and retry, or surface to ops\n\ttime.Sleep(backoff)\n\tready, err = repo.GetReadyWork(ctx, filter)\n}","preventionTips":["Grant SELECT on issues/wisps to the app DB user","Health-check the DB before ready-work computation","Keep schema aligned with the beads version in use","Use IncludeDeferred=true to bypass the probe when acceptable"],"tags":["database","deferred","probe","permissions"],"backgroundTag":"sql-probe-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}