Resolve all four file-validation bugs from #135#136
Merged
Conversation
…etry Two diagnosis fixes from issue #135. Bug 2: ~290 analysis-start-blocked events surfaced raw V8 parse errors like "Unexpected token '<', '<!doctype'..." because safeParseJSON was being called on the output of fetch(jsonBlob) without first checking whether the response was HTML. When HyPhy fails to produce a result file the cliObj.download() path resolves to a 404 HTML page; throwing a clear message gives the user actionable feedback and stops the parser noise in telemetry. Bug 1: 338 of 342 unknown file-validation-error events had no message field because error.message was falsy. Fall back through error.name and error.toString() before resorting to a sentinel string so the analytics payload always has something to work with.
Bug 3: When the datareader doesn't produce an NJ tree (FILE_INFO.nj
missing), the TreeSourceSelector correctly disables the 'inferred'
radio but the underlying selectedTreeSource state stays 'inferred' (the
default). Users then click Run and hit "No NJ tree available". Add a
reactive guard that switches the state to whichever source is actually
available, and tighten the error message when no fallback exists.
Bug 4: Aioli's exec() does a plain command.split(' '), so multi-word
genetic code names like 'Vertebrate mitochondrial' get split into
'--code Vertebrate' + a stray 'mitochondrial' token, which causes HyPhy
to reject 'Vertebrate' and then consume the next option's value as a
fallback ('All' from --branches, '0.1' from --pvalue, 'Source' from
branch labels). Pass the numeric geneticCodeId (always single-token)
instead — the backend already does this.
This was referenced Jun 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Addresses all four bugs from #135 — fixes the actual user-facing failures (Bugs 3 + 4) and the two telemetry gaps that surfaced them (Bugs 1 + 2).
Bug 1 — Unknown errors missing message field (
+page.svelte)338 of 342 `unknown` file-validation-error events had no `message` field in telemetry because `errorMsg = error.message || ''` was empty when something threw without a string. Replace the empty-string fallback with a defensive chain (`error.message → error.name → error.toString() → sentinel`) so the analytics payload always has something to work with.
Bug 2 — HTML responses parsed as JSON (
WasmAnalysisRunner.js)~290 `analysis-start-blocked` events surfaced raw V8 parse errors like `Unexpected token '<', '<!doctype'... is not valid JSON`. The actual culprit was `WasmAnalysisRunner.js:448` calling `safeParseJSON` without first checking whether `fetch(jsonBlob)` had returned HTML (which happens when HyPhy fails to produce a result file and the path resolves to a 404 page). Mirror the existing guard from `+page.svelte:805` so the user sees an actionable message instead of a parser error.
(The issue suggested `BackendAnalysisRunner.js` was at fault, but the backend uses socket.io — there's no `response.json()` there to guard. The real source was the WASM result fetch.)
Bug 3 — Neighbor-joining tree blocked without fallback (
AnalyzeTab.svelte)177 `analysis-start-blocked` events with `No neighbor-joining tree available. Please select a different tree source or upload a tree.` Root cause: `selectedTreeSource` defaults to `'inferred'`, but if datareader didn't produce an NJ tree (`FILE_INFO.nj` missing), the TreeSourceSelector disables the radio button while the underlying state stays `'inferred'`. Users then click Run and `getSelectedTreeData()` returns empty.
Add a reactive guard that switches `selectedTreeSource` to whichever source is actually available (`'uploaded'` if present, otherwise `'upload-new'`). Also tighten the error message when no fallback exists so users understand what to do.
Bug 4 — Genetic code parameter receiving invalid values (
MethodSelector.svelte+WasmAnalysisRunner.js)19+ `'X' is not a valid value for parameter 'Choose Genetic Code'` events with values like `Vertebrate`, `All`, `Source`, `0.1`. Root cause: aioli's `exec()` does a plain `command.split(' ')` with no quote awareness (confirmed by reading the aioli worker source). Multi-word genetic code names like `'Vertebrate mitochondrial'` get split into `--code Vertebrate` + a stray `mitochondrial`, which causes HyPhy to reject `Vertebrate` and then consume the next option's value as a fallback — explaining `'All'` (from `--branches All`), `'0.1'` (from `--pvalue 0.1`), and `'Source'` (from RELAX branch labels).
Pass the numeric `geneticCodeId` (always single-token) as `--code` instead of the descriptive name. The backend already does this via socket params.
Test plan
Follow-ups (out of scope)