{"record":{"id":"721b87c0531ef2e1","repo":"Billionmail/BillionMail","slug":"annotate-s-w","errorCode":null,"errorMessage":"annotate %s: %w","messagePattern":"annotate (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/video_gen/annotate.go","lineNumber":215,"sourceCode":"\t\toutput string\n\t}{\n\t\t{ScreenshotHomepage, result.Homepage, annotated.Homepage},\n\t\t{ScreenshotContact, result.Contact, annotated.Contact},\n\t\t{ScreenshotGoogle, result.Google, annotated.Google},\n\t}\n\n\tfor _, p := range pairs {\n\t\tanns := DefaultAnnotations(p.typ, signals)\n\t\tif len(anns) == 0 {\n\t\t\t// No annotations — just copy\n\t\t\tanns = nil\n\t\t}\n\t\tif err := Annotate(ctx, AnnotateConfig{\n\t\t\tInputPath:   p.input,\n\t\t\tOutputPath:  p.output,\n\t\t\tAnnotations: anns,\n\t\t}); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"annotate %s: %w\", p.typ, err)\n\t\t}\n\t}\n\n\treturn annotated, nil\n}\n\n// annotatedPath derives the annotated output path from the original.\nfunc annotatedPath(original string) string {\n\text := filepath.Ext(original)\n\tbase := strings.TrimSuffix(original, ext)\n\treturn base + \"_annotated\" + ext\n}\n","sourceCodeStart":197,"sourceCodeEnd":228,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/video_gen/annotate.go#L197-L228","documentation":"AnnotateAll iterates over scene types, calling Annotate for each. If any single annotation pass fails, the whole batch aborts and the error is wrapped with the scene type so you know which image failed. It is a pass-through wrapper — the root cause is always in the inner 'imagemagick annotate failed' error.","triggerScenarios":"Annotate returns an error for a scene with type p.typ — magick missing, bad input/output path for that scene, or invalid annotation config for that scene type.","commonSituations":"One scene's screenshot file missing while others succeed; per-scene annotation text/config invalid; ImageMagick installed for some runners but not others; running during pipeline where a prior screenshot step silently failed.","solutions":["Read the wrapped cause: the scene type in this message plus the 'output:' text from the inner error","Check that the input screenshot and output path for that specific scene type exist and are writable","Run the failing scene's magick command manually to isolate the bad argument","Ensure ImageMagick is installed in the environment running AnnotateAll","Add pre-flight validation of scene configs/paths before starting the batch"],"exampleFix":"// before\nif _, err := os.Stat(p.input); err != nil { /* proceeds anyway */ }\n// after\nif _, err := os.Stat(p.input); err != nil {\n    return nil, fmt.Errorf(\"scene %s input missing: %w\", p.typ, err)\n}","handlingStrategy":"validation","validationCode":"for _, p := range scenes {\n    if _, err := os.Stat(p.input); err != nil {\n        return nil, fmt.Errorf(\"scene %s: input missing: %w\", p.typ, err)\n    }\n}\nif err := exec.Command(\"magick\", \"-version\").Run(); err != nil {\n    return nil, errors.New(\"magick not available for annotate batch\")\n}","typeGuard":null,"tryCatchPattern":"annotated, err := video_gen.AnnotateAll(ctx, scenes)\nif err != nil {\n    var sceneErr error\n    if strings.HasPrefix(err.Error(), \"annotate \") {\n        sceneErr = errors.Unwrap(err) // inspect the magick failure for the specific scene\n    }\n    return fmt.Errorf(\"annotate batch aborted: %w (cause: %v)\", err, sceneErr)\n}","preventionTips":["Run the screenshot step's success/failure for every scene before annotating","Pre-validate all scene input/output paths in one pass before starting the batch","Ensure ImageMagick is installed wherever AnnotateAll runs","Consider continuing per-scene and collecting errors instead of failing the whole batch"],"tags":["imagemagick","batch-processing","video-gen","exec"],"backgroundTag":"external-command-failed","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}