{"record":{"id":"167f0eea069685db","repo":"siyuan-note/siyuan","slug":"parse-created-s-failed-w","errorCode":null,"errorMessage":"parse created [%s] failed: %w","messagePattern":"parse created \\[(.+?)\\] failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_render.go","lineNumber":1231,"sourceCode":"\t}\n\tif len(matches) != 1 {\n\t\treturn \"\", fmt.Errorf(\"attribute view snapshot context is ambiguous [%s]\", avID)\n\t}\n\tboxID := avBoxIDFromRepoPath(matches[0].Path)\n\tif IsEncryptedBox(boxID) {\n\t\treturn boxID, nil\n\t}\n\treturn \"\", nil\n}\n\n// ResolveHistoryAttributeViewBoxID 返回历史属性视图的唯一加密笔记本上下文。\nfunc ResolveHistoryAttributeViewBoxID(avID, created string) (string, error) {\n\tif !ast.IsNodeIDPattern(avID) {\n\t\treturn \"\", ErrInvalidID\n\t}\n\tcreatedUnix, err := strconv.ParseInt(created, 10, 64)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"parse created [%s] failed: %w\", created, err)\n\t}\n\tdirPrefix := time.Unix(createdUnix, 0).Format(\"2006-01-02-150405\")\n\tmatches, err := filepath.Glob(filepath.Join(util.HistoryDir, dirPrefix+\"*\"))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tvar boxIDs []string\n\tfor _, historyDir := range matches {\n\t\tif gulu.File.IsExist(filepath.Join(historyDir, \"storage\", \"av\", avID+\".json\")) {\n\t\t\tboxIDs = append(boxIDs, \"\")\n\t\t}\n\t\tentries, _ := os.ReadDir(historyDir)\n\t\tfor _, entry := range entries {\n\t\t\tif !entry.IsDir() || !ast.IsNodeIDPattern(entry.Name()) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcandidate := filepath.Join(historyDir, entry.Name(), \"storage\", \"av\", avID+\".json\")\n\t\t\tif gulu.File.IsExist(candidate) {","sourceCodeStart":1213,"sourceCodeEnd":1249,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view_render.go#L1213-L1249","documentation":"ResolveHistoryAttributeViewBoxID parses the history 'created' timestamp as a Unix seconds integer to build the history directory prefix. If the string is not a valid integer, strconv.ParseInt fails and the error is wrapped with the offending value for diagnostics.","triggerScenarios":"Calling ResolveHistoryAttributeViewBoxID with a created value that is empty, non-numeric, in a wrong format (e.g. ISO date string instead of Unix seconds), or truncated.","commonSituations":"History entries produced by an older version storing a different timestamp format; passing a human-readable date string from UI state; nil/empty field in history metadata.","solutions":["Pass created as a Unix-seconds integer string (e.g. \"1726963200\")","Convert any other timestamp format to Unix seconds before calling","Check the history entry source for corrupted or empty created values"],"exampleFix":"// before\nboxID, err := model.ResolveHistoryAttributeViewBoxID(avID, \"2026-09-18 10:00:00\")\n// after\ncreated := strconv.FormatInt(entry.Created.Unix(), 10)\nboxID, err := model.ResolveHistoryAttributeViewBoxID(avID, created)","handlingStrategy":"validation","validationCode":"createdUnix, err := strconv.ParseInt(created, 10, 64)\nif err != nil { return fmt.Errorf(\"created must be unix seconds, got %q\", created) }","typeGuard":null,"tryCatchPattern":"boxID, err := model.ResolveHistoryAttributeViewBoxID(avID, created)\nif err != nil && strings.HasPrefix(err.Error(), \"parse created\") {\n    return ErrBadHistoryTimestamp\n}","preventionTips":["Always pass Unix-seconds strings for history timestamps","Convert UI date objects with Math.floor(date.getTime()/1000) before sending","Validate history metadata fields at ingestion time"],"tags":["timestamp","parsing","history"],"backgroundTag":"invalid-date-format","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}