Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>AL Griller - AL Code RoastNew to Visual Studio Code? Get it now.
AL Griller - AL Code Roast

AL Griller - AL Code Roast

Yahya Touil

|
2 installs
| (0) | Free
Your AL code is about to get cooked. A local, deterministic static analyzer for Microsoft Dynamics 365 Business Central AL code, presented as funny but technically honest roasts.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

AL Griller

Your AL code is about to get cooked.

AL Griller is a deterministic static analyzer for Microsoft Dynamics 365 Business Central AL code, with a humorous presentation. It is not an AI code reviewer, not a generic linter, and not a joke extension that insults developers at random. Every roast is backed by a real, detectable pattern in your code.

No AI. Local only.

AL Griller does not call OpenAI, Claude, Copilot, or any cloud or LLM API. There are no network calls of any kind. All analysis runs entirely on your machine, on the file you have open. Your source code never leaves your editor.

How it works

  1. Open an AL file.
  2. Click the AL Griller icon in the Activity Bar (or run AL Griller: Grill Current File).
  3. AL Griller scans the active file's text with a set of conservative, deterministic rules.
  4. Findings show up in the AL Griller view, grouped by category, each with a roast and a score.
  5. Click any finding to jump straight to the line it refers to.

Analysis is line/pattern-based, not a full AL grammar parser - it is intentionally conservative, since a false positive is worse than a missed pattern. Re-analysis happens automatically when you switch AL files or edit the current one (debounced), and on demand via AL Griller: Grill Again.

The panel

The findings panel is a webview, not a tree view - on purpose. VS Code's built-in tree items hard-truncate their label with an ellipsis (...) and can't wrap, which meant long roasts got clipped unless you dragged the sidebar uncomfortably wide. The panel now renders each finding as a real card:

  • A circular score badge (color-coded green → red) plus Problem/Warning/Note chips up top
  • Findings grouped into labeled, emoji-tagged category sections
  • The roast is the headline of the card - large, bold, and always fully visible, wrapping naturally at any panel width
  • The rule ID, severity, message, technical explanation, and suggestion are still all there - folded under a "Technical details" toggle so the roast stays the star, and the specifics are one click away
  • A "Jump to line →" button on every card

Roasts

The roasts are not generic "this code could be better" filler - every one is written against the specific pattern that rule detects, not a template. They lean absurd, specific, and a little unhinged, on purpose - code personified having an existential crisis, transactions cosplaying as diplomats, database locks throwing tiny tantrums - while staying clean and never insulting the developer as a person. Each rule ships with 5 roasts; which one shows is picked deterministically per finding, so re-analyzing the same file doesn't rewrite the joke on you.

Main features

  • A rich, scrollable panel in the Activity Bar - not a tree view - so every finding renders as a full card with a score badge, category grouping, and a roast that's never cut off or truncated, no matter how narrow the sidebar is
  • Click "Jump to line →" on any finding to go straight to the offending line
  • Every finding carries both a roast and, tucked under a collapsible "Technical details" toggle, a plain technical explanation and a suggestion where one applies - the roast stays the headline, the explanation stays one click away
  • Deterministic scoring (0–100) computed directly from the findings' severities - never a made-up number
  • Current-file analysis only; no workspace-wide scanning, no background indexing

Rules

AL Griller ships 26 rules, ALGRILL001–ALGRILL026, drawn from a researched, evidence-backed rule database (see the project's RULE_RESEARCH.md). This is the complete and only rule set the analyzer runs - every shipped rule went through the same selection bar: a real, detectable Business Central pattern, with explicit false-positive guards, before it was allowed in.

Because this is a single-file, line/pattern-based scanner with no cross-object symbol resolution, a few rules are intentionally narrower than their full research description - each rule's source comment in rules.ts documents exactly where it approximates and why (for example, ALGRILL001 only recognizes the single-field "No." primary-key case, since resolving an arbitrary table's full primary key would need information outside the current file).

Database

Rule Severity What it flags
ALGRILL001 Warning FindFirst() used when a full primary-key filter (SetRange("No.", ...)) was already applied - Get() fits better
ALGRILL004 Warning FindSet(true)/FindSet() lock intent doesn't match whether the loop actually writes the record
ALGRILL007 Info A FindSet + repeat/Delete/until loop with no per-row logic - DeleteAll(false) fits better

Performance

Rule Severity What it flags
ALGRILL002 Warning Count() > 0 or a discarded FindFirst() used purely as an existence check - IsEmpty() fits better
ALGRILL003 Warning CalcFields() called per row inside a loop to build a running total - CalcSums() fits better
ALGRILL008 Info Text rebuilt with +=/string concatenation on every iteration of a loop - TextBuilder fits better
ALGRILL013 Warning An equality condition is tested inside the loop body instead of filtered with SetRange/SetFilter before FindSet
ALGRILL014 Info A database lookup runs before a guard that may exit the procedure without ever using it

Transactions

Rule Severity What it flags
ALGRILL005 Warning Commit() called inside a loop
ALGRILL015 Warning LockTable() called with no subsequent write in the same procedure
ALGRILL016 Warning Confirm()/StrMenu() issued while a write-intent lock is still open
ALGRILL017 Problem Codeunit.Run() follows a database write with no Commit() in between (this is a guaranteed platform runtime error)

Events

Rule Severity What it flags
ALGRILL010 Warning An integration/business event is raised inside a per-record loop
ALGRILL011 Warning An integration event is raised from inside a [TryFunction] body

Error Handling

Rule Severity What it flags
ALGRILL018 Warning Insert()/Modify()/Delete() runs inside a [TryFunction] body - it will not be rolled back
ALGRILL019 Warning A [TryFunction] procedure is called without consuming its Boolean return value

Data Modeling

Rule Severity What it flags
ALGRILL012 Warning xRec is compared against Rec inside OnModify/OnInsert - from code, they're the same record there
ALGRILL020 Info A field declares both TableRelation and ValidateTableRelation = false - rename propagation silently stops

AL Objects

Rule Severity What it flags
ALGRILL006 Warning Modify() called inside a page's OnAfterGetRecord trigger, which fires once per displayed row
ALGRILL021 Info Get() called inside a page trigger for the record the page already loaded into Rec
ALGRILL023 Warning A ListPart FactBox is declared with no SubPageLink

Query

Rule Severity What it flags
ALGRILL009 Problem Query.SetFilter()/SetRange() called after Open() - this silently closes the running dataset

Security

Rule Severity What it flags
ALGRILL024 Warning A permission set grants access with a wildcard (tabledata * / table *) object designator
ALGRILL025 Warning IsolatedStorage.Set() (unencrypted) is used for a key/value that looks like a credential
ALGRILL026 Warning A credential-named variable or parameter is typed Text/Code instead of SecretText

Code Quality

Rule Severity What it flags
ALGRILL022 Info FieldError() is called with a capitalized, punctuated, or field-name-restating message

AL Griller complements the AL Language extension and Microsoft's built-in analyzers (CodeCop, AppSourceCop, PerTenantExtensionCop) rather than duplicating them - no rule in this database re-flags a pattern already covered by a Microsoft analyzer.

Scoring

Score starts at 100. Each finding subtracts a fixed penalty based on its severity: Problem −12, Warning −6, Info −2, floored at 0. It's a quick read of a file, not a substitute for looking at the findings.

Example roast

🔴 ALGRILL003 · Performance

"CalcFields() got summoned once per row like a tiny genie who can only grant
one wish before vanishing back into the lamp, forever, on repeat."

▸ Technical details
  CustLedgerEntry.CalcFields("Remaining Amount") runs once per iteration to
  build a running total.

  CalcFields() materializes a FlowField value for one record and issues its
  own SQL statement against a persistent table. Calling it inside a loop
  that iterates many rows issues one query per row on top of the iteration
  itself. CalcSums() answers the same aggregation question over the filtered
  set as a single SQL statement.

  Suggestion: Replace the per-row CalcFields() + accumulation with a single
  CalcSums() call on the filtered record before or instead of the loop.

Requirements

  • VS Code ^1.85.0
  • No runtime npm dependencies. typescript, @types/vscode, and @types/node are dev-time only, used to compile the extension - none of them ship or run with it.

Marketplace

AL Griller is available on the Visual Studio Marketplace. Search for AL Griller, or install it from the Extensions view in VS Code (Ctrl+Shift+X).


Contributing

Pull requests are welcome - this project benefits a lot from community input, whether that's new rules, bug fixes, or better roasts. If you're a junior AL developer, contributing here is also a good way to learn more about AL development patterns by seeing what gets flagged and why. Roast quality is subjective, so feedback on tone and jokes is just as welcome as feedback on the rules themselves. Have an idea or found a bug? Open an issue on the GitHub Issues page.


License

Released under the MIT License. You're free to use, modify, and distribute this software, subject to the license terms.


Feedback & Support

Questions or issues? Open an issue on GitHub, or reach out to the community for support and suggestions.


Made with ❤️ by Yahya Touil.

More Business Central and AL development insights on Yahya's Blog.

AL Griller - Built for Business Central AL developers.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft