{"record":{"id":"f548ff4b116ea472","repo":"larksuite/cli","slug":"resolve-save-path-empty-result-for-q","errorCode":null,"errorMessage":"resolve save path: empty result for %q","messagePattern":"resolve save path: empty result for %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"shortcuts/common/runner.go","lineNumber":658,"sourceCode":"\t\treturn p.ResolveFileIO(c)\n\t}\n\treturn nil\n}\n\n// ResolveSavePath resolves a relative path to a validated absolute path via\n// FileIO.ResolvePath. It returns an error if no FileIO provider is registered\n// or if the path fails validation (e.g. traversal, symlink escape).\nfunc (ctx *RuntimeContext) ResolveSavePath(path string) (string, error) {\n\tfio := ctx.FileIO()\n\tif fio == nil {\n\t\treturn \"\", fmt.Errorf(\"no file I/O provider registered\")\n\t}\n\tresolved, err := fio.ResolvePath(path)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"resolve save path: %w\", err)\n\t}\n\tif resolved == \"\" {\n\t\treturn \"\", fmt.Errorf(\"resolve save path: empty result for %q\", path)\n\t}\n\treturn resolved, nil\n}\n\n// WrapOpenError matches a FileIO.Open/Stat error and wraps it with the\n// caller-provided message prefix.\nfunc WrapOpenError(err error, pathMsg, readMsg string) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\tif errors.Is(err, fileio.ErrPathValidation) {\n\t\treturn fmt.Errorf(\"%s: %w\", pathMsg, err)\n\t}\n\treturn fmt.Errorf(\"%s: %w\", readMsg, err)\n}\n\n// WrapInputStatErrorTyped wraps a FileIO.Stat/Open error for input file\n// validation, returning a typed validation error with the appropriate message:","sourceCodeStart":640,"sourceCodeEnd":676,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/common/runner.go#L640-L676","documentation":"FileIO.ResolvePath returned success but an empty string, which the library treats as a contract violation: a resolved save path must always be a non-empty absolute path. This defensive check catches providers that silently return nothing instead of an error.","triggerScenarios":"A FileIO provider implementation bug (or misconfigured base directory) causing ResolvePath to return (\"\", nil) for the given input path.","commonSituations":"Custom or stub FileIO providers returning empty results; a provider configured with an empty/missing base directory; plugin hosts implementing the FileIO interface incorrectly.","solutions":["Fix or correctly configure the FileIO provider so ResolvePath always returns a non-empty validated path for valid input","Verify the provider's base directory is set (non-empty) in the runtime configuration","If you maintain a custom provider, add a check returning an explicit error when the computed path is empty"],"exampleFix":"// before\nresolved := filepath.Join(base, path) // base may be \"\"\nreturn resolved, nil\n// after\nif resolved == \"\" { return \"\", fmt.Errorf(\"resolve path: empty result for %q\", path) }\nreturn resolved, nil","handlingStrategy":"type-guard","validationCode":"resolved, err := ctx.ResolveSavePath(path)\nif err != nil || resolved == \"\" {\n\treturn errs.NewValidationError(errs.SubtypeFailedPrecondition, \"path resolver returned no path\")\n}","typeGuard":"func validSavePath(p string, err error) bool { return err == nil && p != \"\" && filepath.IsAbs(p) }","tryCatchPattern":"out, err := ctx.ResolveSavePath(path)\nif err != nil {\n\tif strings.Contains(err.Error(), \"empty result\") {\n\t\t// FileIO provider bug/misconfig: check base dir\n\t}\n\treturn err\n}","preventionTips":["Ensure the FileIO provider's base directory is configured and non-empty","Treat empty resolver output as a provider bug and fail fast","Add a regression test asserting ResolvePath never returns (\"\", nil) for valid input"],"tags":["go","file-io","path-resolution","contract-violation"],"backgroundTag":"empty-resolved-path","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}