{"record":{"id":"60d848ca9a48b955","repo":"gastownhall/beads","slug":"setting-issue-prefix-w","errorCode":null,"errorMessage":"setting issue_prefix: %w","messagePattern":"setting issue_prefix: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/embeddeddolt/store.go","lineNumber":763,"sourceCode":"\t\t}\n\n\t\t// Import config entries (memories, etc.)\n\t\tfor key, value := range configEntries {\n\t\t\tif err := issueops.SetConfigInTx(ctx, tx, key, value); err != nil {\n\t\t\t\treturn fmt.Errorf(\"importing config %q: %w\", key, err)\n\t\t\t}\n\t\t}\n\n\t\tif len(issues) == 0 {\n\t\t\treturn nil\n\t\t}\n\n\t\t// Auto-detect prefix from first issue if not already provided\n\t\tif _, hasPrefix := configEntries[\"issue_prefix\"]; !hasPrefix {\n\t\t\tfirstPrefix := utils.ExtractIssuePrefix(issues[0].ID)\n\t\t\tif firstPrefix != \"\" {\n\t\t\t\tif err := issueops.SetConfigInTx(ctx, tx, \"issue_prefix\", firstPrefix); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"setting issue_prefix: %w\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Create all issues in the same transaction\n\t\tif err := issueops.CreateIssuesInTx(ctx, tx, issues, actor, storage.BatchCreateOptions{\n\t\t\tSkipPrefixValidation: true,\n\t\t\t// Defense-in-depth (GH#3955): the embedded fast-path is the primary\n\t\t\t// auto-import route for 1.0+ users and is gated by the in-transaction\n\t\t\t// emptiness check above. Make it insert-if-new too so a regression in\n\t\t\t// that check cannot clobber live rows — matching the server-mode\n\t\t\t// fallback's conflict-skip behavior.\n\t\t\tConflictSkip: true,\n\t\t}); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\timported = len(issues)","sourceCodeStart":745,"sourceCodeEnd":781,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/embeddeddolt/store.go#L745-L781","documentation":"Wraps the error from SetConfigInTx when auto-detecting and persisting the issue_prefix config: if the caller's configEntries lacks \"issue_prefix\", the store extracts the prefix from the first issue's ID (utils.ExtractIssuePrefix) and writes it in the same import transaction. Failure means the config row write failed (SQL error, table missing, transaction issue), rolling back the entire import so the database remains empty and the import retryable.","triggerScenarios":"Import where configEntries has no \"issue_prefix\" and: (1) the config table is absent due to unmigrated schema; (2) the write fails from connection loss or ctx cancellation mid-transaction; (3) a constraint error on the config table. Only triggered when len(issues) > 0 and the first issue's ID yields a non-empty prefix (e.g. \"bd-123\" → \"bd\").","commonSituations":"Importing a hand-edited or tool-generated issues.jsonl whose IDs lack a recognizable prefix (prefix extracted as empty is skipped — but malformed IDs with odd prefixes can still exercise this path); importing into a database whose schema wasn't migrated; CI cancellation during import.","solutions":["Migrate the schema first ('bd migrate'), then retry the import.","Explicitly pass issue_prefix in configEntries so the auto-detect write path is skipped and the prefix is deterministic.","Check the wrapped inner SQL error for the root cause (missing table vs. connection).","Retry — the transactional rollback makes re-import safe.","Validate that issue IDs in the import file follow the expected 'prefix-N' format."],"exampleFix":"// before\nstore.ImportIssues(ctx, issues, map[string]string{}) // prefix auto-detected from \"weird_id_1\"\n\n// after\nstore.ImportIssues(ctx, issues, map[string]string{\"issue_prefix\": \"bd\"})","handlingStrategy":"validation","validationCode":"// decide the prefix up front to skip auto-detection\nprefix := \"bd\"\nif len(issues) > 0 {\n    if p := utils.ExtractIssuePrefix(issues[0].ID); p != \"\" { prefix = p }\n}\ncfg[\"issue_prefix\"] = prefix","typeGuard":null,"tryCatchPattern":"err := store.ImportIssues(ctx, issues, cfg)\nif err != nil && strings.Contains(err.Error(), \"setting issue_prefix\") {\n    // transaction rolled back; supply explicit prefix and retry\n    cfg[\"issue_prefix\"] = \"bd\"\n    return store.ImportIssues(ctx, issues, cfg)\n}","preventionTips":["Always pass an explicit issue_prefix in configEntries for deterministic imports","Validate imported issue IDs match 'prefix-N' format","Migrate the schema before import","Use a dedicated, non-cancelled context for imports"],"tags":["embedded-dolt","sql","config","import"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}