{"record":{"id":"a97b93fbbbb5280d","repo":"gastownhall/beads","slug":"dependency-created-at-is-zero-for-s-s","errorCode":null,"errorMessage":"dependency created_at is zero for %s -> %s","messagePattern":"dependency created_at is zero for (.+?) -> (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/migration/legacysqlite/reader.go","lineNumber":920,"sourceCode":"\t}\n\tissue := byID[id]\n\tif issue == nil || byID[to] == nil {\n\t\treturn fmt.Errorf(\"orphan dependency %s -> %s\", id, to)\n\t}\n\tif issue.Ephemeral != byID[to].Ephemeral {\n\t\treturn fmt.Errorf(\"dependency %s -> %s crosses ephemeral storage\", id, to)\n\t}\n\tkey := id + \"\\x00\" + to\n\tif seenDeps[key] {\n\t\treturn fmt.Errorf(\"multiple legacy dependencies for %s -> %s\", id, to)\n\t}\n\tseenDeps[key] = true\n\tcreated, e := parseTime(at)\n\tif e != nil {\n\t\treturn e\n\t}\n\tif created.IsZero() {\n\t\treturn fmt.Errorf(\"dependency created_at is zero for %s -> %s\", id, to)\n\t}\n\tif (metadata.Valid && metadata.String != \"\") || (thread.Valid && thread.String != \"\") {\n\t\treturn fmt.Errorf(\"dependency %s -> %s uses unsupported metadata or thread ID\", id, to)\n\t}\n\tif !types.DependencyType(typ).IsValid() {\n\t\treturn fmt.Errorf(\"dependency %s -> %s has invalid type\", id, to)\n\t}\n\td := &types.Dependency{IssueID: id, DependsOnID: to, Type: types.DependencyType(typ), CreatedAt: created, CreatedBy: by, Metadata: nullString(metadata), ThreadID: nullString(thread)}\n\tissue.Dependencies = append(issue.Dependencies, d)\n\treturn nil\n}\n\nfunc loadComments(ctx context.Context, db *sql.Tx, byID map[string]*types.Issue) error {\n\tcomments, err := db.QueryContext(ctx, \"SELECT id,issue_id,author,text,CAST(created_at AS TEXT) FROM comments ORDER BY issue_id,created_at,id\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer comments.Close()","sourceCodeStart":902,"sourceCodeEnd":938,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/migration/legacysqlite/reader.go#L902-L938","documentation":"The migration reader parses each dependency's created_at timestamp and rejects the import when the parsed time is the zero time.Time. A zero timestamp means the legacy row has no usable creation date, and bd requires every dependency to carry a real CreatedAt for ordering and display.","triggerScenarios":"Legacy SQLite dependency rows whose created_at column is NULL, empty, or stored in a format `parseTime` resolves to the zero value; the pair id -> to is reported.","commonSituations":"Very old legacy databases predating the created_at column on dependencies; rows hand-inserted via SQL without a timestamp; corrupted or out-of-format date strings.","solutions":["Backfill created_at for the offending dependency rows in the legacy DB (e.g. UPDATE dependencies SET created_at = <iso timestamp> WHERE created_at IS NULL OR created_at = '')","Re-run migration after repair; if parseTime still fails on format, normalize the column format to the expected RFC3339-style layout","Exclude/recreate the dependency manually in bd after migration if the timestamp cannot be recovered"],"exampleFix":"-- before\n-- dependencies row: ('bd-1','bd-2',NULL)\nUPDATE dependencies SET created_at = '2024-01-15T10:00:00Z'\nWHERE created_at IS NULL OR created_at = '';\n-- after: row has a real timestamp","handlingStrategy":"validation","validationCode":"for (const d of legacyDeps) {\n  if (!d.created_at || new Date(d.created_at).getTime() === 0 || isNaN(Date.parse(d.created_at)))\n    throw new Error(`zero/invalid created_at on ${d.issue_id} -> ${d.depends_on_id}`);\n}","typeGuard":"function hasCreatedAt(d) {\n  return typeof d.created_at === 'string' && d.created_at !== '' && !isNaN(Date.parse(d.created_at));\n}","tryCatchPattern":"try { migrateLegacySQLite(dbPath) } catch (e) {\n  if (e.message.includes('created_at is zero')) {\n    const m = e.message.match(/for (\\S+) -> (\\S+)/);\n    backfillDepCreatedAt(dbPath, m[1], m[2]);\n    retry();\n  } else throw e;\n}","preventionTips":["Backfill NULL/empty created_at columns before migration","Enforce NOT NULL on created_at in the legacy schema","Normalize all timestamps to RFC3339 before importing"],"tags":["migration","sqlite","timestamp"],"backgroundTag":"missing-created-at","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}