{"record":{"id":"17a9659c07a2c72c","repo":"gastownhall/beads","slug":"importing-config-q-w","errorCode":null,"errorMessage":"importing config %q: %w","messagePattern":"importing config %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/embeddeddolt/store.go","lineNumber":750,"sourceCode":"\tissues []*types.Issue,\n\tconfigEntries map[string]string,\n\tactor string,\n) (int, error) {\n\tvar imported int\n\terr := s.withConn(ctx, true, func(tx *sql.Tx) error {\n\t\t// Atomically check: is the database empty?\n\t\tstats := &types.Statistics{}\n\t\tif err := issueops.ScanIssueCountsInTx(ctx, tx, stats); err != nil {\n\t\t\treturn fmt.Errorf(\"checking issue count: %w\", err)\n\t\t}\n\t\tif stats.TotalIssues > 0 {\n\t\t\treturn nil // database is not empty — skip import\n\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","sourceCodeStart":732,"sourceCodeEnd":768,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/embeddeddolt/store.go#L732-L768","documentation":"Wraps the error from SetConfigInTx while writing each config entry (key/value, e.g. memories) inside the import transaction. The issue-count check passed (database is empty), but persisting a config row failed — SQL error such as a missing/corrupt config table, constraint violation, or connection/context failure. Because this happens inside the import transaction, the whole import transaction is rolled back, leaving the database still empty and the import safely retryable.","triggerScenarios":"Import path with configEntries where: (1) the config table doesn't exist (unmigrated schema); (2) a duplicate-key or constraint error on the config key; (3) ctx cancelled mid-loop; (4) transaction connection lost after several writes.","commonSituations":"Importing into a freshly created but unmigrated database; importing a .beads/issues.jsonl export whose config keys collide with an existing (partially imported) dataset; long imports cancelled by CI timeouts.","solutions":["Apply migrations first ('bd migrate' or open once via bd) so the config table exists, then retry.","Inspect the wrapped key (%q) and inner SQL error to find the offending config entry.","Retry the import — transactional rollback keeps the DB empty, so a rerun is idempotent.","Sanitize/canonicalize config keys in the source export if a specific key is malformed."],"exampleFix":"// before\nentries := map[string]string{\"issue_prefix\": \"bd\", \"issue_prefix \": \"xx\"} // duplicate/odd key\nstore.ImportIssues(ctx, issues, entries)\n\n// after\ndelete(entries, \"issue_prefix \") // remove conflicting key\nstore.ImportIssues(ctx, issues, entries)","handlingStrategy":"retry","validationCode":"for key := range configEntries {\n    if strings.TrimSpace(key) == \"\" || strings.ContainsAny(key, \"\\n\\r\") {\n        return fmt.Errorf(\"invalid config key %q\", key)\n    }\n}","typeGuard":null,"tryCatchPattern":"err := store.ImportIssues(ctx, issues, cfg)\nif err != nil && strings.Contains(err.Error(), \"importing config\") {\n    // rollback already happened; fix offending key per error text, then retry\n    return store.ImportIssues(ctx, issues, sanitizeConfig(cfg))\n}","preventionTips":["Migrate the schema before importing","Deduplicate and normalize config keys in source exports","Use one long-lived context for the entire import","Rely on transaction rollback: failed imports leave the DB empty and retryable"],"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"}