{"record":{"id":"fb3e41b9ad595d09","repo":"gastownhall/beads","slug":"legacy-sqlite-issue-s-created-at-w","errorCode":null,"errorMessage":"legacy SQLite issue %s created_at: %w","messagePattern":"legacy SQLite issue (.+?) created_at: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/migration/legacysqlite/reader.go","lineNumber":541,"sourceCode":"\t\t}\n\t\tif err := checkJSONSurrogates(x.waiters.String); err != nil {\n\t\t\treturn fmt.Errorf(\"issue %s waiters: %w\", issue.ID, err)\n\t\t}\n\t\twaiters, err := decodeWaiters(x.waiters.String)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"issue %s waiters: %w\", issue.ID, err)\n\t\t}\n\t\tissue.Waiters = waiters\n\t}\n\treturn nil\n}\n\n// applyCanonicalTimestamps normalizes the required created_at/updated_at values\n// to the canonical current-schema representation.\nfunc (x legacyExtras) applyCanonicalTimestamps(issue *types.Issue) error {\n\tvar err error\n\tif issue.CreatedAt, err = canonicalCurrentDatetime(issue.CreatedAt); err != nil {\n\t\treturn fmt.Errorf(\"legacy SQLite issue %s created_at: %w\", issue.ID, err)\n\t}\n\tif issue.UpdatedAt, err = canonicalCurrentDatetime(issue.UpdatedAt); err != nil {\n\t\treturn fmt.Errorf(\"legacy SQLite issue %s updated_at: %w\", issue.ID, err)\n\t}\n\treturn nil\n}\n\n// checkRequiredScalars enforces the non-empty ID, non-tombstone status, and\n// present created_at/updated_at invariants every legacy issue must satisfy.\nfunc checkRequiredScalars(issue *types.Issue) error {\n\tif issue.ID == \"\" {\n\t\treturn fmt.Errorf(\"legacy SQLite issue has empty ID\")\n\t}\n\tif issue.Status == \"tombstone\" {\n\t\treturn fmt.Errorf(\"legacy SQLite issue %s is a tombstone\", issue.ID)\n\t}\n\tif issue.CreatedAt.IsZero() || issue.UpdatedAt.IsZero() {\n\t\treturn fmt.Errorf(\"legacy SQLite issue %s has invalid created_at or updated_at\", issue.ID)","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/migration/legacysqlite/reader.go#L523-L559","documentation":"applyCanonicalTimestamps normalizes legacy created_at values to the canonical current-schema datetime via canonicalCurrentDatetime. This error means the issue's created_at value could not be parsed/normalized — it is not a recognizable timestamp format. Migration refuses to import an issue with an unusable creation timestamp.","triggerScenarios":"Legacy row has created_at stored as an empty string, a non-timestamp string, or a format canonicalCurrentDatetime does not accept (e.g. locale-formatted dates, milliseconds-as-string, or NULL coerced oddly).","commonSituations":"Databases touched by other tools that wrote their own date formats, rows created by very old beads versions with a different timestamp convention, or corrupted rows from a crashed writer.","solutions":["Find the row: sqlite3 legacy.db \"SELECT id, created_at FROM issues WHERE id='<id>'\" and inspect the raw value","Rewrite created_at to an ISO-8601 / RFC-3339 UTC timestamp the current code accepts, e.g. '2024-01-15T10:30:00Z'","If the true creation time is unknown, set a best-effort timestamp (e.g. rowid-derived or mtime of the DB file)","Re-run the migration"],"exampleFix":"// before\ncreated_at = '01/15/2024 10:30 AM'\n// after\ncreated_at = '2024-01-15T10:30:00Z'","handlingStrategy":"validation","validationCode":"from datetime import datetime\ndef ts_ok(v):\n    if not v:\n        return False\n    try:\n        datetime.fromisoformat(v.replace('Z', '+00:00'))\n        return True\n    except ValueError:\n        return False\n# bad = [r['id'] for r in rows if not ts_ok(r['created_at'])]","typeGuard":"def is_canonical_datetime(v) -> bool:\n    if not isinstance(v, str) or not v:\n        return False\n    try:\n        datetime.fromisoformat(v.replace('Z', '+00:00'))\n        return True\n    except ValueError:\n        return False","tryCatchPattern":null,"preventionTips":["Audit timestamp formats across the legacy DB before migrating","Standardize on ISO-8601 UTC in any tooling that writes issue timestamps","Dry-run validation on a copy of the DB first"],"tags":["migration","sqlite","timestamps"],"backgroundTag":"invalid-timestamp-format","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}