{"record":{"id":"4971db71f8280521","repo":"pinpoint-apm/pinpoint","slug":"could-not-resolve-placeholder-placeholder-in-s","errorCode":null,"errorMessage":"Could not resolve placeholder '<placeholder>' in string value \"<strVal>\"","messagePattern":"Could not resolve placeholder '<placeholder>' in string value \"<strVal>\"","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"commons-config/src/main/java/com/navercorp/pinpoint/common/config/util/spring/PropertyPlaceholderHelper.java","lineNumber":167,"sourceCode":"                        propVal = placeholderResolver.apply(actualPlaceholder);\n                        if (propVal == null) {\n                            propVal = defaultValue;\n                        }\n                    }\n                }\n                if (propVal != null) {\n                    // Recursive invocation, parsing placeholders contained in the\n                    // previously resolved placeholder value.\n                    propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);\n                    buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);\n                    startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());\n                }\n                else if (this.ignoreUnresolvablePlaceholders) {\n                    // Proceed with unprocessed value.\n                    startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());\n                }\n                else {\n                    throw new IllegalArgumentException(\"Could not resolve placeholder '\" +\n                            placeholder + \"'\" + \" in string value \\\"\" + strVal + \"\\\"\");\n                }\n                visitedPlaceholders.remove(originalPlaceholder);\n            }\n            else {\n                startIndex = -1;\n            }\n        }\n\n        return buf.toString();\n    }\n\n    private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {\n        int index = startIndex + this.placeholderPrefix.length();\n        int withinNestedPlaceholder = 0;\n        while (index < buf.length()) {\n//            if (StringUtils.substringMatch(buf, index, this.placeholderSuffix)) {\n            // copy spring StringUtils","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/commons-config/src/main/java/com/navercorp/pinpoint/common/config/util/spring/PropertyPlaceholderHelper.java#L149-L185","documentation":"parseStringValue() resolves each ${...} placeholder via the supplied resolver function. If no value can be resolved and ignoreUnresolvablePlaceholders is false (as in ValueAnnotationProcessor's instance and any helper built with ignore=false), it throws IllegalArgumentException naming both the placeholder and the original string being processed. When ignoreUnresolvablePlaceholders is true, the raw ${...} text is left in place instead.","triggerScenarios":"A @Value(\"${some.key}\") annotation references a key absent from the resolver's properties map (with no ':' default), and the helper is strict; also nested resolution where the inner resolved key still cannot be found.","commonSituations":"Environment-specific property files missing a key that exists in other environments; renamed config keys after an upgrade while old @Value references remain; typo in the placeholder key inside the annotation; missing system environment variable that the resolver would map.","solutions":["Add the missing key to the properties file / environment so the resolver finds it","Provide an inline default in the annotation, e.g. @Value(\"${some.key:defaultValue}\")","Fix the placeholder key spelling in the @Value annotation to match the actual property name","Build the PropertyPlaceholderHelper with ignoreUnresolvablePlaceholders=true if raw text is acceptable"],"exampleFix":"// before\n@Value(\"${collector.span.batch:size_missing}\")\nprivate int batchSize;\n// after\n@Value(\"${collector.span.batch:1024}\")\nprivate int batchSize;","handlingStrategy":"validation","validationCode":"String key = \"collector.span.batch\";\nif (!properties.containsKey(key)) {\n    throw new IllegalStateException(\"Missing config key: \" + key);\n}","typeGuard":null,"tryCatchPattern":"try {\n    processor.process(configInstance, resolver);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Could not resolve placeholder\")) {\n        log.error(\"Missing property: {}\", e.getMessage());\n    }\n}","preventionTips":["Always supply inline defaults: @Value(\"${key:default}\") for optional settings","Keep environment property files synchronized — check new keys into every env file","Grep for ${...} keys in @Value annotations and diff them against the properties files at build time","Remember a missing key yields either this error (strict helper) or null/silent skip via getValue()'s catch of IllegalArgumentException"],"tags":["configuration","placeholders","missing-property","properties"],"backgroundTag":"missing-config-key","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}