Financial analysis
Model Risk Report
Load an Excel model and see what is risky about how it is built — circular references, numbers typed into formulas, a formula quietly overridden by a constant, numbers stored as text, a check row that is not reconciling, sheets that feed each other. Every finding names the sheet and cell, so you can open it and look. It is a spreadsheet audit of how the model is built: it never opens a linked workbook and never runs a macro.
Drop an .xlsx or .xlsm workbook, or click to choose one
Read in your browser. The file is never uploaded.
Your workbook is read locally in your browser and is not uploaded to Consilium. Nothing in it is sent anywhere, stored, or logged.
Transparent by design
How this report is produced
Your file is read in this browser and is not uploaded. Every check below runs over what the file itself records — its cells and formulas, the names it defines, the formats it declares, its tables, validations, links, connections and document properties. Nothing is inferred about your business, and no figure in your model is recalculated: a check row is reported as failing because the value the file saved is not zero, not because this tool worked the row out again. Every finding is a fact about the file, produced by reading it; the tool contains no model call, and the same workbook always produces the same report.
What it will not tell you is whether the model is right. This reports how a workbook is built, never whether its conclusions are sound.
What runs
- Checks
- 55
- Check families covered
- 37
- Sections
- 7
- Engine
- browser-0.3.1
The engine version changes when a change would alter the findings for a workbook that has not changed.
The severity ladder
- Critical
- 1
- High
- 10
- Medium
- 20
- Low
- 10
- Info
- 14
A severity is a property of the check, not of your model: it says how much a finding of that kind would matter if it were true, before anyone looks. Nothing is ever favourable — a finding is not good news.
The bars it applies
- Volatile calls per sheet
- 20
- Conditional formats per sheet
- 50
- Connections
- 5
- Unused styles
- 50
- Sheet chain depth
- 4
- Mega formula tokens
- 120
- Fill run minimum
- 4
- Fill run dominance
- 0.6
Each bar is printed beside the finding it produced, so a reader who disagrees with one can see it. None has been tuned against a real model.
Numbers a formula may hold without being remarked on
-1 · 0 · 1 · 2 · 12 · 100 · 365 · 360 · 1000
A hardcoded number inside a formula is reported unless it is one of these — the handful too common to remark on, such as a sign flip, a percentage base, a count of months, or a day-count convention.
Every check, and what it looks for
Codes identify each check and its check family, so you can match a finding to the description and thresholds below.
Formula and calculation
10Broken links, circular references, hardcodes, overridden formulas, volatile functions and errors that spread.
- C01_broken_nameMediumCheck family 1
Entries in the workbook’s defined-name table that point at a range which no longer exists.
- C01_external_linkMediumCheck family 1
Every other file this workbook draws values from, taken from its external link targets.
Let past: Those files are never opened, so their values are not checked.
- C02_circular_refHighCheck family 2
Cycles in the cell dependency graph, where a chain of formulas feeds back into itself.
- C03_literal_in_formulaInfoCheck family 3
Numeric literals typed inside a formula, once quoted text, references and function-name digits are stripped out.
Let past: The benign constants list — the handful too common to remark on.
- C03_plugHighCheck family 3
An interior cell of a fill run holding a constant, or a formula whose shape differs from the run’s dominant template.
The bars: fill run minimum 4, and fill run dominance 0.6.
Let past: Each run’s first and last cell, where a seed or a total legitimately sits.
- C04_volatile_overuseMediumCheck family 4
Sheets where the count of volatile function calls, which recalculate on every workbook change, passes the threshold.
The bar: volatile calls per sheet 20.
- C06_error_valueMediumCheck family 6
Cells whose stored value is an Excel error, grouped by the error and reported as contiguous blocks.
- C06_error_cascadeHighCheck family 6
For each cell holding an error, the cells reading it directly or indirectly, and how many sheets they span.
Let past: Error cells that no other cell reads.
- C07_anchoring_deviatesMediumCheck family 7
An interior cell of a fill run whose formula matches the run’s shape but whose dollar anchoring differs from it.
The bars: fill run minimum 4, and fill run dominance 0.6.
Let past: Each run’s first and last cell, where a seed or a total legitimately sits.
- C08_whole_column_refMediumCheck family 8
Formulas referencing a whole column or whole row instead of a bounded range, grouped by the reference used.
Data integrity
10Numbers and dates that are really text, invisible characters, and columns that mix currencies or scales.
- C05_array_spill_collisionHighCheck family 5
Cells already holding a value or formula inside the range an array formula recorded itself as filling.
Let past: Single-cell array ranges, the formula’s own cell, and empty cells.
- C09_number_as_textHighCheck family 9
Cells stored as text whose content reads as a number: plain, thousands-separated, or a bracketed negative.
Let past: Left-padded digit strings, read as account codes rather than arithmetic.
- C10_date_as_textHighCheck family 10
Text cells matching a date shape, grouped by shape, noting where day and month cannot be told apart.
- C10_mixed_date_formatLowCheck family 10
A column whose date-formatted cells carry more than one number-format code, naming every code in use.
Let past: Cells whose number format does not render a date, including text dates.
- C11_hidden_row_in_rangeHighCheck family 11
Aggregating functions whose range spans a row or column the sheet hides, so hidden lines still enter the total.
Let past: SUBTOTAL and AGGREGATE, which can be told to skip hidden rows.
- C12_stray_whitespaceMediumCheck family 12
Text cells holding a non-breaking space, an invisible character, a control character, or leading or trailing spaces.
Let past: Tab, newline and carriage return.
- C13_blank_in_tableMediumCheck family 13
Empty cells below the header row of an Excel Table or AutoFilter range, clustered into contiguous blocks.
Let past: The header row, and informal blocks the file never declares as structured.
- C14_merged_cellLowCheck family 14
Merged ranges on a sheet, reported separately according to whether they overlap a declared table or filtered range.
- C15_duplicate_rowMediumCheck family 15
Rows inside a declared table or filtered range matching another row’s values and formulas in every column.
Let past: The header row, and wholly empty rows, which the blank check reports.
- C16_mixed_number_formatMediumCheck family 16
A column whose non-date numeric cells state more than one combination of currency symbol and thousands scaling.
Let past: Cells whose format states no currency symbol and no scaling.
Structure and architecture
11How the model is laid out: assumptions buried in calculations, sheets that feed each other, names that clash, inputs nothing describes.
- C17_input_in_calc_rowMediumCheck family 17
Rows where a formula reads a hand-typed constant sitting on the same row and the same sheet as that formula.
Let past: Inputs a formula reads from another row or another sheet.
- C18_mega_formulaMediumCheck family 18
The token count of each formula, reported at or above the threshold, naming its bracket-nesting depth as well.
The bar: mega formula tokens 120.
- C19_sheet_pair_loopHighCheck family 19
Pairs of sheets whose formulas reference each other in both directions, so neither can be read as the source.
- C19_reference_depthLowCheck family 19
The longest chain of sheets a value crosses before use, reported when that chain reaches the threshold.
The bar: sheet chain depth 4.
Let past: Shorter chains; only the longest in the workbook is reported.
- C20_overlapping_nameMediumCheck family 20
Defined names covering overlapping cells, or the same name defined at both workbook and sheet scope.
Let past: Names marked broken, and names whose target cannot be parsed as a rectangle.
- C20_dead_nameLowCheck family 20
Defined names that no formula anywhere in the workbook mentions.
Let past: Names marked broken, which another check reports.
- C21_default_sheet_nameLowCheck family 21
Sheet names still matching Excel’s default pattern — a stock word and a trailing digit — across several language versions.
- C21_version_suffix_nameLowCheck family 21
Sheet names that are identical once a trailing version word or short number is stripped, reported as a group.
Let past: Year-like trailing numbers, so sheets named by year are not paired.
- C22_unlabelled_inputMediumCheck family 22
Hand-typed constants a formula reads with no text cell to their left on the row or above in the column.
Let past: Typed values no formula reads, and text cells, which are not inputs.
- C23_hidden_sheetInfoCheck family 23
Sheets whose visibility is set to hidden, with how many populated cells each one holds.
- C23_very_hidden_sheetLowCheck family 23
Sheets set to very hidden, which the Excel menu cannot unhide, with how many populated cells each holds.
Audit and control
5The model’s own controls — and whether they are currently passing.
- C25_unprotected_sheetInfoCheck family 25
Sheets that hold formulas and carry no sheet protection, so any formula on them can be overtyped.
Let past: Sheets holding no formulas at all.
- C25_unlocked_formulaMediumCheck family 25
Formula cells whose lock flag is off on a sheet that is protected, so the protection does not reach them.
Let past: Unprotected sheets, reported instead as their own finding.
- C26_input_without_validationInfoCheck family 26
Hand-typed constants that a formula reads and that no data-validation rule’s stated range covers.
Let past: Constants no formula reads, and cells inside a validation range.
- C27_dead_conditional_formatMediumCheck family 27
Conditional-format rules whose range or formulas carry a deleted-reference marker, so they highlight nothing.
- C28_failing_check_rowCriticalCheck family 28
A formula returning a number away from zero whose nearest label names a check, difference, variance, tie-out, reconciliation or control row.
Let past: Hand-typed cells, non-numeric results, and partial word matches, so “Invariant” does not count.
Performance and scalability
5What forces the workbook to recalculate more than it needs to.
- C29_conditional_format_volumeLowCheck family 29
The count of conditional-format rules on each sheet, reported where it passes the threshold.
The bar: conditional formats per sheet 50.
- C30_unused_stylesInfoCheck family 30
The cell formats the file declares against those any cell uses, reporting the unused remainder against the threshold.
The bar: unused styles 50.
- C31_connection_volumeLowCheck family 31
The count of external data connections the workbook declares, reported where it passes the threshold.
The bar: connections 5.
Let past: Whether any connection actually refreshes.
- C32_local_path_sourceMediumCheck family 32
Connection sources beginning with a drive letter, a UNC share or a file URL, which resolve on only one computer.
- C33_volatile_reachMediumCheck family 33
Every cell downstream of a volatile call, counted, being what recalculates whenever anything in the workbook changes.
Let past: The volatile cells themselves, counted separately from the cells they reach.
Security and compliance
7What the file itself says about protection and macros. Never a judgement about whether data is sensitive.
- C34_macros_unsignedHighCheck family 34
The workbook carries a macro project and that project carries no digital signature.
Let past: Macro code, which is neither executed nor analysed.
- C34_macros_signedInfoCheck family 34
The workbook carries a macro project and that project carries a digital signature.
Let past: Whether the signature can be trusted; no certificate chain is verified.
- C35_unlocked_cell_inventoryInfoCheck family 35
Sheets holding cells that carry no protection, plus the unlocked cells sitting on the sheets that are protected.
Let past: Sheets holding no cells.
- C35_structured_identifierHighCheck family 35
Text that verifies as an email address, a card number passing the Luhn check, or an IBAN whose check digits verify.
Let past: Values that resemble identifiers but fail their own check digits. Nothing is judged by appearance.
- C36_insecure_linkMediumCheck family 36
Data-connection sources and cell hyperlinks whose address begins with http rather than https.
- C37_removable_protectionInfoCheck family 37
Which sheets are marked protected, and that the protection password removes without decrypting the file.
- C38_metadata_contentsInfoCheck family 38
Document properties naming author, last editor, company, manager, custom entries and comment authors, which travel with the file.
What was not checked
7Every check this tool did not run, named. A check that did not run is not a check that passed.
- COV_unreadableInfo
A sheet named in the workbook whose own data part is missing or cannot be located, so it went unread.
- COV_protected_contentInfo
Each sheet that declares worksheet protection.
Let past: The protection is reported, never bypassed; the sheet’s cells are still read.
- COV_vba_presentMedium
The archive contains a VBA macro project part.
Let past: The macro code itself, which is never executed or analysed.
- COV_array_formulaInfo
Each cell whose formula is recorded as an array formula.
Let past: Its evaluation: the formula is recorded, never calculated.
- COV_unresolved_linkInfo
Each target the workbook’s external-link parts point at.
Let past: The linked file, never opened, so its values go unchecked.
- COV_cap_hitLow
Reading stopped because the reader’s cell budget ran out, leaving the report incomplete.
Let past: Every cell past the cap, which was never read.
- COV_not_performedInfo
One entry per fixed statement of what this tool does not check, whatever the workbook holds.
What this tool will never check
These checks cannot be established from one file, or would require a judgement this tool leaves to you.
- Version control and change tracking are not checked. A single .xlsx does not record its own history, so there is nothing in the file to read.
- Whether a linked file's values are current is not checked. The linked file is named but never opened.
- Whether a query or connection refreshes successfully is not checked. A saved file records what a connection points at, not what happened last time it ran.
- Whether a macro's signature is trusted is not checked. Presence of a signature is a fact; whether its certificate chains to a root you trust cannot be established in a browser.
- Nothing is judged to be sensitive, confidential, cryptic, excessive or untraceable. Where a check could only be made by that kind of judgement, this tool reports the measurement instead and leaves the judgement to you.
Current coverage gaps
Named here and on every report, because a check that did not run is not a check that passed.
- Drawing and shape bloat is not measured. Phantom shapes and orphaned drawing parts can inflate a file, but those parts of the file are not read. Unused cell styles are checked separately.