{"record":{"id":"c463dc9e05d325c9","repo":"jaegertracing/jaeger","slug":"file-must-begin-with","errorCode":null,"errorMessage":"file must begin with '['","messagePattern":"file must begin with '\\['","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/anonymizer/app/uiconv/reader.go","lineNumber":57,"sourceCode":"\t\tcapturedFile: cf,\n\t\treader:       bufio.NewReader(cf),\n\t}, nil\n}\n\n// NextSpan reads the next span from the capture file, or returns errNoMoreSpans.\nfunc (r *spanReader) NextSpan() (*uimodel.Span, error) {\n\tif r.eofReached {\n\t\treturn nil, errNoMoreSpans\n\t}\n\tif r.spansRead == 0 {\n\t\tb, err := r.reader.ReadByte()\n\t\tif err != nil {\n\t\t\tr.eofReached = true\n\t\t\treturn nil, fmt.Errorf(\"cannot read file: %w\", err)\n\t\t}\n\t\tif b != '[' {\n\t\t\tr.eofReached = true\n\t\t\treturn nil, errors.New(\"file must begin with '['\")\n\t\t}\n\t}\n\ts, err := r.reader.ReadString('\\n')\n\tif err != nil {\n\t\tr.eofReached = true\n\t\treturn nil, fmt.Errorf(\"cannot read file: %w\", err)\n\t}\n\tif s[len(s)-2] == ',' { // all but last span lines end with ,\\n\n\t\ts = s[0 : len(s)-2]\n\t} else {\n\t\tr.eofReached = true\n\t}\n\tvar span uimodel.Span\n\terr = json.Unmarshal([]byte(s), &span)\n\tif err != nil {\n\t\tr.eofReached = true\n\t\treturn nil, fmt.Errorf(\"cannot unmarshal span: %w; %s\", err, s)\n\t}","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/anonymizer/app/uiconv/reader.go#L39-L75","documentation":"lengthOfTime reads a constant that must represent a duration and parses it via expression.ReadConstant with FieldTypeDuration. When the constant's text is not a valid duration string (e.g. \"2s\", \"100ms\"), ReadConstant fails and the filter is rejected as invalid, wrapping tracestore.ErrFilterInvalid so callers can detect it with errors.Is. This happens when a duration comparison (e.g. duration > X) is built from a tree whose constant was not finalized into a DurationValue.","triggerScenarios":"Calling a trace search whose filter compares the duration field against a constant written in an unrecognized format, e.g. duration > \"two seconds\" or duration >= \"5\" without a unit; the constant reaches lengthOfTime via buildDurationComparison without having been finalized into a DurationValue.","commonSituations":"Typing a duration filter without a time unit in a query UI or API request; writing durations in human phrasing (\"2 seconds\") instead of Go-style duration syntax; a query built programmatically without running finalization on the expression tree.","solutions":["Write the duration constant as a valid Go-style duration string with a unit, e.g. \"2s\", \"100ms\", \"1h\".","Ensure the expression tree is finalized before filtering so typed constants become expression.DurationValue instead of raw untyped constants.","Check the wrapped inner error (errors.Is/As on ErrFilterInvalid) to surface the parse failure message to the end user."],"exampleFix":"// before\n{\"duration\": {\"gt\": \"2sec\"}}\n// after\n{\"duration\": {\"gt\": \"2s\"}}","handlingStrategy":"validation","validationCode":"func validDuration(s string) bool {\n    _, err := time.ParseDuration(s)\n    return err == nil\n}\n// check before submitting: validDuration(\"2s\")","typeGuard":"func asDuration(e expression.Expression) (*expression.DurationValue, bool) {\n    d, ok := e.(*expression.DurationValue)\n    return d, ok\n}","tryCatchPattern":"q, err := buildFilterQuery(...)\nif errors.Is(err, tracestore.ErrFilterInvalid) {\n    // surface parse message to user, fix duration syntax like \"2s\"\n}","preventionTips":["Always include a unit in duration literals: 2s, 100ms, 1h.","Run expression finalization before filtering so constants become DurationValue.","Unit-test duration filters with ParseDuration-valid strings."],"tags":["query-filter","duration-parse","elasticsearch"],"backgroundTag":"invalid-duration-format","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}