{"record":{"id":"66d2eb976d0dfd9a","repo":"go-delve/delve","slug":"cannot-use-s-as-substitutepath-of-type-from","errorCode":null,"errorMessage":"cannot use %s as 'substitutePath' of type {\"from\":string, \"to\":string}","messagePattern":"cannot use (.+?) as 'substitutePath' of type (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/dap/types.go","lineNumber":255,"sourceCode":"// For example, mapping with empty 'to' can be used to work with binaries with trimmed paths.\ntype SubstitutePath struct {\n\t// The local path to be replaced when passing paths to the debugger.\n\tFrom string `json:\"from,omitempty\"`\n\t// The remote path to be replaced when passing paths back to the client.\n\tTo string `json:\"to,omitempty\"`\n}\n\nfunc (m *SubstitutePath) UnmarshalJSON(data []byte) error {\n\t// use custom unmarshal to check if both from/to are set.\n\ttype tmpType struct {\n\t\tFrom *string\n\t\tTo   *string\n\t}\n\tvar tmp tmpType\n\n\tif err := json.Unmarshal(data, &tmp); err != nil {\n\t\tif _, ok := err.(*json.UnmarshalTypeError); ok {\n\t\t\treturn fmt.Errorf(`cannot use %s as 'substitutePath' of type {\"from\":string, \"to\":string}`, data)\n\t\t}\n\t\treturn err\n\t}\n\tif tmp.From == nil || tmp.To == nil {\n\t\treturn errors.New(\"'substitutePath' requires both 'from' and 'to' entries\")\n\t}\n\t*m = SubstitutePath{*tmp.From, *tmp.To}\n\treturn nil\n}\n\n// AttachConfig is the collection of attach request attributes recognized by DAP implementation.\n// 'processId' and 'waitFor' are mutually exclusive, and can't be specified at the same time.\ntype AttachConfig struct {\n\t// Acceptable values are:\n\t//   \"local\": attaches to the local process with the given ProcessID.\n\t//   \"remote\": expects the debugger to already be running to \"attach\" to an in-progress debug session.\n\t//\n\t// Default is \"local\".","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/service/dap/types.go#L237-L273","documentation":"Each element of the launch/attach config's substitutePath array must be a JSON object with string fields 'from' and 'to'. A JSON value of the wrong type (e.g. a string, number, or array) appeared where such an object was expected, so custom UnmarshalJSON returns this descriptive error instead of the raw Go type error.","triggerScenarios":"onLaunchRequest/onAttachRequest where substitutePath contains a non-object entry, e.g. \"substitutePath\": [\"/a\"] or [ {\"from\":1,\"to\":\"/b\"} ].","commonSituations":"Users copying old string-array substitutePath syntax from other debuggers, hand-edited launch.json, or schema-less editors not validating the object shape.","solutions":["Make every substitutePath entry an object: {\"from\":\"<remote>\",\"to\":\"<local>\"}","Ensure both 'from' and 'to' are present string values (missing fields give a related error)","Validate launch.json against the DAP/delve schema in your editor","Quote values as strings — numbers and booleans are rejected"],"exampleFix":"// before\n\"substitutePath\": [\"/remote/src\"]\n// after\n\"substitutePath\": [{\"from\": \"/remote/src\", \"to\": \"/local/src\"}]","handlingStrategy":"validation","validationCode":"func validSubstitutePath(sp []json.RawMessage) error {\n  for _, r := range sp {\n    var o map[string]any\n    if err := json.Unmarshal(r, &o); err != nil { return err }\n    f, okF := o[\"from\"].(string); t, okT := o[\"to\"].(string)\n    if !okF || !okT { return fmt.Errorf(\"entry %s must be {from:string,to:string}\", r) }\n  }\n  return nil\n}","typeGuard":"func isSubstitutePathEntry(v any) bool {\n  m, ok := v.(map[string]any); if !ok { return false }\n  _, okF := m[\"from\"].(string); _, okT := m[\"to\"].(string)\n  return okF && okT\n}","tryCatchPattern":"if _, err := unmarshalLaunchAttachArgs(raw); err != nil { if strings.Contains(err.Error(), \"substitutePath\") { /* fix launch.json to object entries */ } return err }","preventionTips":["Always model substitutePath as an array of {from,to} objects","Enable launch.json schema validation in your editor","Migrate legacy string-array configs explicitly"],"tags":["dap","json","launch-config"],"backgroundTag":"schema-validation-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}