{"record":{"id":"4c83dc3fb768e134","repo":"ZhuLinsen/daily_stock_analysis","slug":"backend-executable-not-found-backendpath","errorCode":null,"errorMessage":"Backend executable not found: ${backendPath}","messagePattern":"Backend executable not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/dsa-desktop/main.js","lineNumber":1187,"sourceCode":"function startBackend({ port, envFile, dbPath, logDir, host = null }) {\n  const backendPath = resolveBackendPath();\n  backendStartError = null;\n  const launchStartedAt = Date.now();\n  const bindHost = normalizeBackendBindHost(\n    normalizeBackendHost(host) || resolveBackendBindHost({ envFile }),\n    DESKTOP_BACKEND_DEFAULT_HOST\n  );\n\n  const env = buildBackendEnvironment({ envFile, dbPath, logDir, port, host: bindHost });\n\n  const args = buildBackendArgs({ host: bindHost, port });\n  let launchMode = '';\n  let launchCommand = '';\n  let launchCwd = '';\n\n  if (backendPath) {\n    if (!fs.existsSync(backendPath)) {\n      throw new Error(`Backend executable not found: ${backendPath}`);\n    }\n    launchMode = 'packaged';\n    launchCommand = formatCommand(backendPath, args);\n    launchCwd = path.dirname(backendPath);\n    backendProcess = spawn(backendPath, args, {\n      env,\n      cwd: launchCwd,\n      stdio: 'pipe',\n      windowsHide: true,\n    });\n  } else {\n    const pythonPath = resolvePythonPath();\n    const scriptPath = path.join(appRootDev, 'main.py');\n    const pythonArgs = ['-X', 'utf8', scriptPath, ...args];\n    launchMode = 'development';\n    launchCommand = formatCommand(pythonPath, pythonArgs);\n    launchCwd = appRootDev;\n    backendProcess = spawn(pythonPath, pythonArgs, {","sourceCodeStart":1169,"sourceCodeEnd":1205,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/apps/dsa-desktop/main.js#L1169-L1205","documentation":"Raised by PortfolioService.add_corporate_action when the symbol argument cannot be normalized to a canonical stock code. The service calls canonical_stock_code(symbol) via _normalize_symbol_for_storage (portfolio_service.py:1255) and rejects empty/None/unrecognized symbols before writing, because a corporate action row without a valid symbol would poison position replay.","triggerScenarios":"Calling add_corporate_action(account_id=..., symbol=None), symbol=\"\", symbol=\"   \", or a symbol string that canonical_stock_code cannot map (e.g. 'NOSUCH', '???'). The check happens inside the portfolio_write_session, after market/currency normalization but before add_corporate_action_in_session.","commonSituations":"Import scripts or UI forms that submit an empty symbol field; passing a ticker with only whitespace; feeding a raw exchange code that the data_provider canonicalizer does not recognize (e.g. invented tickers or placeholder values during testing).","solutions":["Pass a recognized symbol format: A-share '600519' or 'SH600519' or '600519.SH', HK 'HK00700' or '00700.HK', US 'AAPL'","If symbol comes from user input, validate/strip it in the caller before calling the service","Check that the symbol string is non-empty after strip(); whitespace-only input is rejected","Log the raw symbol value at the call site to identify which upstream producer sends bad symbols"],"exampleFix":"# before\nsvc.add_corporate_action(account_id=1, symbol=\"\", action_type=\"cash_dividend\", cash_dividend_per_share=0.5, effective_date=d)\n# after\nsvc.add_corporate_action(account_id=1, symbol=\"600519\", action_type=\"cash_dividend\", cash_dividend_per_share=0.5, effective_date=d)","handlingStrategy":"validation","validationCode":"from data_provider.base import canonical_stock_code\n\ndef valid_corp_action_symbol(symbol):\n    return bool((canonical_stock_code(symbol or \"\") or \"\").strip())","typeGuard":"def is_actionable_symbol(symbol: str | None) -> bool:\n    \"\"\"True when add_corporate_action will accept the symbol.\"\"\"\n    return bool(symbol and (canonical_stock_code(symbol) or \"\").strip())","tryCatchPattern":"try:\n    svc.add_corporate_action(...)\nexcept ValueError as exc:\n    if \"symbol is required\" in str(exc):\n        # surface a field-level error to the form\n        raise UserInputError(\"symbol\", str(exc)) from exc\n    raise","preventionTips":["Validate symbols with the same canonical_stock_code used by the service","Make symbol a required field in UI forms and API schemas","Reject whitespace-only and placeholder values in import tooling"],"tags":["portfolio","validation","symbol","corporate-action"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}