arduino/Arduino · error · Exception
'Invalid quoting: no closing [' + escapingChar + '] char fou
Error message
'Invalid quoting: no closing [' + escapingChar + '] char found.'
What it means
StringReplacer.quotedSplit splits a formatted command string into arguments honoring quoting/escaping characters (e.g. quotes around paths with spaces). If the string ends while an escaping/quoting char is still open (no closing quote), it throws Exception("Invalid quoting: no closing [<char>] char found."). This guards against unbalanced quotes in recipes or command templates.
Source
Thrown at arduino-core/src/processing/app/helpers/StringReplacer.java:121
}
escapingChar = first;
i = i.substring(1);
escapedArg = "";
}
if (!i.endsWith(escapingChar)) {
escapedArg += i + " ";
continue;
}
escapedArg += i.substring(0, i.length() - 1);
if (escapedArg.trim().length() != 0 || acceptEmptyArguments)
res.add(escapedArg);
escapingChar = null;
}
if (escapingChar != null)
throw new Exception("Invalid quoting: no closing [" + escapingChar +
"] char found.");
return res.toArray(new String[0]);
}
public static String replaceFromMapping(String src, Map<String, String> map) {
return replaceFromMapping(src, map, "{", "}");
}
public static String replaceFromMapping(String src, Map<String, String> map,
String leftDelimiter,
String rightDelimiter) {
for (Map.Entry<String, String> entry : map.entrySet()) {
String keyword = leftDelimiter + entry.getKey() + rightDelimiter;
if (entry.getValue() != null && keyword != null) {
src = src.replace(keyword, entry.getValue());
}
}
return src;View on GitHub (pinned to a0df6e0e83)
Solutions
- Open the recipe/template string and balance the quotes around the reported character
- Count quote characters in the offending pattern to find the odd one
- Escape literal quote characters if they are part of a value rather than delimiters
- Reinstall/restore the original platform.txt if the recipe was corrupted by editing
Example fix
// before
recipe.c.combine.pattern="{compiler.c.elf.cmd} {object_files} -o {build.path}/{build.project_name}.elf " // trailing space ate the closing quote intent
// after
recipe.c.combine.pattern="{compiler.c.elf.cmd} {object_files} -o {build.path}/{build.project_name}.elf" Defensive patterns
Strategy: validation
Validate before calling
int count = 0;
for (char c : pattern.toCharArray()) if (c == '"') count++;
if (count % 2 != 0) throw new IllegalStateException("Unbalanced quotes in: " + pattern); Try / catch
try {
String[] args = StringReplacer.formatAndSplit(src, dict);
} catch (Exception e) {
if (e.getMessage().contains("Invalid quoting"))
logger.error("Fix quotes in pattern: " + src);
else throw e;
} Prevention
- Count quotes when hand-editing recipes
- Avoid quote characters inside filenames/paths
- Test custom recipes with a dry run before real builds
- Restore original recipes from the platform package after bad edits
When it happens
Trigger: Calling quotedSplit (directly or via formatAndSplit) on a string where a quote/escape character opened but never closed — e.g. a recipe value like ""{compiler.path}gcc -o "{build.path}/out"" missing its final quote, or odd number of escaping chars.
Common situations: Hand-edited platform.txt recipes with unbalanced quotes; paths with quotes stripped or mangled by shell/JSON escaping; copy-paste of recipes losing a trailing quote; values containing unbalanced quote characters in filenames.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of arduino/Arduino@a0df6e0e83 (2026-09-06).
Data as JSON: /api/errors/44e833470405e889.
Report an issue: GitHub.