gastownhall/beads · error

parse created_at: %w

Error message

parse created_at: %w

What it means

BeadsIssueFromPullIssue could not parse the pulled issue's CreatedAt string into a timestamp via parseMappingTimestamp. The wrap preserves the time parsing error (missing layout match). The input is issue.CreatedAt as a string, expected in the format produced by the Notion pull/export pipeline.

Source

Thrown at internal/notion/mapping.go:87

}

// BeadsIssueFromPullIssue converts one pulled Notion issue into a beads core issue.
func BeadsIssueFromPullIssue(issue PulledIssue, config *MappingConfig) (*types.Issue, error) {
	if config == nil {
		config = DefaultMappingConfig()
	}

	status := statusToBeads(issue.Status, config)
	priority := priorityToBeads(issue.Priority, config)
	issueTypeRaw := issue.IssueType
	if strings.TrimSpace(issueTypeRaw) == "" {
		issueTypeRaw = issue.Type
	}
	issueType := typeToBeads(issueTypeRaw, config)

	createdAt, hasCreated, err := parseMappingTimestamp(string(issue.CreatedAt))
	if err != nil {
		return nil, fmt.Errorf("parse created_at: %w", err)
	}
	updatedAt, hasUpdated, err := parseMappingTimestamp(string(issue.UpdatedAt))
	if err != nil {
		return nil, fmt.Errorf("parse updated_at: %w", err)
	}
	now := time.Now().UTC()
	if !hasCreated {
		createdAt = now
	}
	if !hasUpdated {
		updatedAt = createdAt
	}

	beadsIssue := &types.Issue{
		ID:           strings.TrimSpace(issue.ID),
		Title:        strings.TrimSpace(issue.Title),
		Description:  strings.TrimSpace(issue.Description),
		Status:       status,

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped time.ParseError: it names the offending value and the layouts tried.
  2. Normalize the source data to RFC3339 (e.g. time.Time.UTC().Format(time.RFC3339)) before pulling.
  3. If the field may be absent, set it to null/omit it so hasCreated=false kicks in rather than passing an unparseable string.
  4. Check the parseMappingTimestamp accepted layouts and emit one of those formats in your exporter.

Example fix

// before
issue.CreatedAt = "01/02/2024 10:00" // unparseable
bead, err := BeadsIssueFromPullIssue(issue, config) // parse created_at error

// after
created, _ := time.Parse("01/02/2006 15:04", "01/02/2024 10:00")
issue.CreatedAt = types.String(created.UTC().Format(time.RFC3339))
Defensive patterns

Strategy: validation

Validate before calling

if _, err := time.Parse(time.RFC3339, createdAt); err != nil {
    return fmt.Errorf("invalid created_at %q: %w", createdAt, err)
}

Try / catch

if err != nil && strings.Contains(err.Error(), "parse created_at") {
    log.Printf("bad created_at value from source: %v", err)
}

Prevention

When it happens

Trigger: CreatedAt containing a format outside the accepted layouts (e.g. 'yesterday', unix seconds, RFC1123, or a Notion date with different precision); an empty-but-non-nil string when the exporter expected absent (nil) for unknown; locale-formatted dates from hand-edited exports.

Common situations: Custom importer/pre-processor writing timestamps in a non-RFC3339 format; JSON produced by another tool with epoch-millis numbers serialized as strings; timezone names instead of offsets ('2024-01-01 10:00:00 EST'); truncated timestamps ('2024-01-01T10:').

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/aedf11140348c885. Report an issue: GitHub.