{"record":{"id":"3b1191a1b6c72bb0","repo":"arduino/Arduino","slug":"could-not-open-join-argv","errorCode":null,"errorMessage":"'Could not open ' + join(argv, ' ')","messagePattern":"'Could not open ' \\+ join\\(argv, ' '\\)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"arduino-core/src/processing/app/legacy/PApplet.java","lineNumber":430,"sourceCode":"      // If the 'open', 'gnome-open' or 'cmd' are already included\n      if (params[0].equals(argv[0])) {\n        // then don't prepend those params again\n        return exec(argv);\n      } else {\n        params = concat(params, argv);\n        return exec(params);\n      }\n    } else {\n      return exec(argv);\n    }\n  }\n\n  static public Process exec(String[] argv) {\n    try {\n      return Runtime.getRuntime().exec(argv);\n    } catch (Exception e) {\n      e.printStackTrace();\n      throw new RuntimeException(\"Could not open \" + join(argv, ' '));\n    }\n  }\n\n  static public String[] concat(String a[], String b[]) {\n    String c[] = new String[a.length + b.length];\n    System.arraycopy(a, 0, c, 0, a.length);\n    System.arraycopy(b, 0, c, a.length, b.length);\n    return c;\n  }\n\n  /**\n   * Identical to match(), except that it returns an array of all matches in\n   * the specified String, rather than just the first.\n   */\n  static public String[][] matchAll(String what, String regexp) {\n    Pattern p = Pattern.compile(regexp, Pattern.MULTILINE | Pattern.DOTALL);\n    Matcher m = p.matcher(what);\n    ArrayList<String[]> results = new ArrayList<>();","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/arduino/Arduino/blob/a0df6e0e83b652c72bc78b0a1376c54d6ebc3bee/arduino-core/src/processing/app/legacy/PApplet.java#L412-L448","documentation":"PApplet.exec launches an external process via Runtime.getRuntime().exec(argv) and, if that throws any Exception, wraps the failure in a RuntimeException \"Could not open <argv joined by spaces>\". It is used by PApplet.open to open files/URLs with the platform's default handler. The original exception is printed to stderr before the RuntimeException is thrown.","triggerScenarios":"Calling PApplet.open(...) / exec(...) when Runtime.exec fails — typically the command does not exist on the platform (e.g. 'xdg-open' missing on Linux, 'open'/'explorer' unavailable), or argv is empty/malformed.","commonSituations":"Minimal/headless Linux installs without xdg-open; trying to open URLs or files in environments without a desktop; security managers blocking process creation; malformed command arrays with empty elements.","solutions":["Check stderr for the underlying IOException printed before the RuntimeException — usually 'Cannot run program: No such file'","Install the platform opener (e.g. xdg-utils on Linux for xdg-open)","Verify the file/URL you are opening exists and the command array is well-formed","Wrap open() calls and fall back to an explicit command (e.g. firefox <url>) when the runtime exception occurs"],"exampleFix":"// before\nPApplet.open(url); // RuntimeException on systems without xdg-open\n// after\ntry {\n  PApplet.open(url);\n} catch (RuntimeException e) {\n  Runtime.getRuntime().exec(new String[]{\"firefox\", url});\n}","handlingStrategy":"try-catch","validationCode":"String opener = System.getProperty(\"os.name\").contains(\"Linux\") ? \"xdg-open\" : \"open\";\nif (Runtime.getRuntime().exec(new String[]{\"which\", opener}).waitFor() != 0)\n  throw new IllegalStateException(\"No desktop opener installed (e.g. xdg-utils)\");","typeGuard":null,"tryCatchPattern":"try {\n  PApplet.open(target);\n} catch (RuntimeException e) {\n  logger.warn(\"open failed, falling back: \" + e.getMessage());\n  // read stderr: underlying exec error was printed by PApplet.exec\n}","preventionTips":["Install xdg-utils on minimal Linux systems","Don't call open() in headless/server environments","Check stderr for the root exec error when debugging","Validate the URL/file path before opening","Prefer Desktop.getDesktop().browse()/open() with isDesktopSupported() checks"],"tags":["process-execution","runtime","arduino-legacy","cross-platform"],"backgroundTag":"command-not-found","analyzedSha":"a0df6e0e83b652c72bc78b0a1376c54d6ebc3bee","analyzedAt":"2026-09-06T10:13:38.901Z","contentChangedAt":"2026-09-06T10:13:38.901Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}