GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Report bindings that have no effect on ng-container, ng-template, and ng-content · Issue #71881 · angular/angular

Report bindings that have no effect on ng-container, ng-template, and ng-content #71881

New issue
Copy link
New issue
Copy link
Open
Open
Report bindings that have no effect on ng-container, ng-template, and ng-content#71881
Copy link
Labels
area: compilerIssues related to `ngc`, Angular's template compilerIssues related to `ngc`, Angular's template compiler
Milestone
needsTriage

Description

@Flarette
Flarette
opened on Nov 8, 2026
Issue body actions

Which @angular/* package(s) are relevant/related to the feature request?

compiler, compiler-cli, core

Description

<ng-container>, <ng-template>, and <ng-content> don't render an element. Angular accepts
bindings and attributes on them that can never take effect, and most of them compile and run
without a word:

<ng-container class="card" [class.active]="isActive" (click)="select()">...</ng-container>
<ng-template [title]="label" (click)="missing()">...</ng-template>
<ng-content selector="h1" />

Nothing on these lines does anything:

  • Class, style, and event bindings on <ng-container> and <ng-template> are ignored, unless a
    directive claims them.
  • Bindings that no directive claims on <ng-template> aren't type-checked, so
    (click)="missing()" compiles.
  • <ng-content> ignores every binding, and every attribute except select and ngProjectAs. The
    selector typo (for select) silently makes the slot a default slot. Angular's own upgrade
    examples have had this typo since 2017.
  • NO_ERRORS_SCHEMA hides unknown properties on <ng-container>, although no schema can give it
    a property.
  • Inside <svg>, [attr.x] on <ng-container> skips its parse error and throws a misleading
    assertion in dev mode.

Proposed solution

Report what Angular ignores, and nothing that takes effect. Code generation and runtime behavior
don't change.

Step 1, not breaking:

  • NG8031 ignoredBinding, a new type-check diagnostic. It needs
    strictTemplates, is a warning by default, and is configured through
    extendedDiagnostics.checks, like NG8011. It reports class, style, attr., animation, and
    event bindings that no directive claims, every binding on <ng-content>, and static attributes
    that nothing reads.
  • NG8032, a template type-check warning for a component whose selector matches
    <ng-container> or <ng-template>. That compiles today and fails only when the template
    renders, in dev and production mode.
  • The language service stops suggesting DOM attributes on <ng-container>.
  • NG0319, a dev-mode runtime log for class, style, and event bindings on <ng-container> and
    <ng-template>, so JIT is covered too.
  • The <svg> parse fix.

Step 2, breaking: severities only, in two independent PRs.

  • NG8032 is an error.
  • NG8031 is an error by default, and NG0319 throws under errorOnUnknownProperties.

Every new error points at a binding or component that never worked. NG8031 can be set back to
"warning" or "suppress".

Not reported: bindings a directive claims, directive host bindings (directives are reusable),
global event targets, and static attributes that a directive, a structural directive, a content
projection slot, or Angular itself reads.

Question for the team: are the step 2 PRs fine for a minor release, or should they wait for a
major? They can land separately.

PRs: #71882 (step 1); #71883 (NG8032 error) and #71884 (NG8031 error), each building on #71882

Alternatives considered

  • A template parse error. The linker re-parses published libraries, so a parse error would
    break libraries that compile today.
  • Only an extended diagnostic. It can warn, but step 2 needs the same check in the type
    checker. One check in the type checker serves both levels.
  • Only a runtime error. It reports late, in dev mode only, and can't see bindings on
    <ng-content> or which static attributes something reads.
  • Also reporting directive host bindings. A directive can apply to elements where those
    bindings work, so reporting them would be noise.

Activity

  1. angular-robot
    added
    area: compilerIssues related to `ngc`, Angular's template compilerIssues related to `ngc`, Angular's template compiler
    on Nov 8, 2026
  2. angular-robot
    added this to the needsTriage milestone on Nov 8, 2026
  3. ngbot
    added this to the needsTriage milestone on Nov 8, 2026
  4. SkyZeroZx commented on Nov 8, 2026

    @SkyZeroZx
    SkyZeroZx
    on Nov 8, 2026
    Contributor
    More actions

    This reminds me a bit of #69640 for unclaimed bindings on ng-template, and #70808 / #71844 for class bindings on ng-container. In #70808, which mentioned:

    Those are never applied and we should throw at compiler time.

    The ng-content part was also discussed in #24259 and #68715, where it was mentioned:

    Is this maybe more appropriate as a template diagnostic or eslint? Breaking compilation on something entirely innocuous seems maybe incorrect.

    I see this proposal covers more cases, but I think some of these checks could also be handled by ESLint.

    So I think maybe we can comment in that issue or PR

  5. Flarette commented on Nov 8, 2026

    @Flarette
    Flarette
    on Nov 8, 2026
    ContributorAuthor
    More actions

    This reminds me a bit of #69640 for unclaimed bindings on ng-template, and #70808 / #71844 for class bindings on ng-container. In #70808, which mentioned:

    Those are never applied and we should throw at compiler time.

    The ng-content part was also discussed in #24259 and #68715, where it was mentioned:

    Is this maybe more appropriate as a template diagnostic or eslint? Breaking compilation on something entirely innocuous seems maybe incorrect.

    I see this proposal covers more cases, but I think some of these checks could also be handled by ESLint.

    So I think maybe we can comment in that issue or PR

    I think the proliferation of agents makes the value of compiler diagnostics higher. Also not everybody uses ESLint and oxlint doesn't even support Angular templates.
    Fixing compilation for this case is now as easy as a asking agent to "fix it". Every error was silently ignored no-op anyway. This makes it explicit.

  6. Flarette commented on Nov 8, 2026

    @Flarette
    Flarette
    on Nov 8, 2026
    ContributorAuthor
    More actions

    Also this one is warning only, it can go into the next release. 2 linked pr's that flip it to error can be shipped with the next major (or minor). I haven't seen the other 2 since it was developed in parallel. This one adds a blanked no-op binding reports for everything while others seems to be a special cases.

  7. JeanMeche commented on Nov 8, 2026

    @JeanMeche
    JeanMeche
    on Nov 8, 2026
    Member
    More actions

    static classes are valid selectors for content projection, we should probably not regress on this.

  8. Flarette commented on Nov 8, 2026

    @Flarette
    Flarette
    on Nov 8, 2026
    ContributorAuthor
    More actions

    static classes are valid selectors for content projection, we should probably not regress on this.

    Agreed, and that’s kept: NG8031 doesn’t report static attributes, class included, on a node that a specific <ng-content select> slot selects. Slot matching includes class names, so select=".card-body" counts. A static class is reported only when no directive matches the node and no specific slot selects it, which is when it has no effect. I’ll add a test for the class case to #71882.

  9. JeanMeche commented on Nov 8, 2026

    @JeanMeche
    JeanMeche
    on Nov 8, 2026
    Member
    More actions

    Fyi, About ng-template I was testing things on #71887 and it raised a behavior that was implemented by #53457.

  10. Flarette commented on Nov 8, 2026

    @Flarette
    Flarette
    on Nov 8, 2026
    ContributorAuthor
    More actions

    Fyi, About ng-template I was testing things on #71887 and it raised a behavior that was implemented by #53457.

    Thanks for flagging it. #71882 keeps that behavior. On an explicit <ng-template>, it treats [attr.x], [class.x], and [style.x] as property bindings named x, as the compiler has done since #53457 (compilesToProperty). A directive input named x claims them, so NG8031 only reports the ones nothing claims.

    Covered in ignored_bindings_spec.ts:

    • should not report a class binding on ng-template (p-input-dir [class.p])
    • should not report a style binding on ng-template (p-input-dir [style.p])
    • should not report an attribute binding on ng-template (p-input-dir [attr.p])
    • should report a class binding on ng-template and should report an attribute binding on ng-template (no directive claims them)

    The ng_template_bindings compliance test from #53457 stays as it is.

    Is this the behavior you ran into on #71887, or was it something else?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: compilerIssues related to `ngc`, Angular's template compilerIssues related to `ngc`, Angular's template compiler

    Type

    No type

    Projects

    No projects

      Milestone

      • needsTriageNo due date

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.