Skip to content

GitHub license detection returns NOASSERTION due to LICENSE.md wrapper file #2024

@gwpl

Description

@gwpl

AI Assistant:

Problem

GitHub's license detection (licensee) returns NOASSERTION for this repository instead of recognizing the dual Apache-2.0 OR MIT license. This means the repo shows "Other" on the GitHub UI instead of the correct license badge.

Programmatic verification

You can verify the issue (and later confirm the fix) with a single gh api call:

# Current: returns "NOASSERTION" — detection failure
gh api repos/visjs/vis-timeline --jq '.license.spdx_id'
# Expected: "Apache-2.0" or ideally recognition of dual license

For comparison, vis-network (which uses a different file layout) is detected correctly:

# Returns "Apache-2.0" — detection works
gh api repos/visjs/vis-network --jq '.license.spdx_id'

Root Cause

The license files in this repo are:

LICENSE.md               ← markdown wrapper with links (not actual license text)
LICENSE.Apache-2.0.txt
LICENSE.MIT.txt

GitHub's licensee fuzzy-matches the root LICENSE file content against known license templates. LICENSE.md contains only a short description with links to the other two files — it doesn't match any known template, so licensee gives up and returns NOASSERTION.

Meanwhile, vis-network uses this layout (which works):

LICENSE-APACHE-2.0       ← full Apache 2.0 text (detected by GitHub)
LICENSE-MIT              ← full MIT text

licensee finds LICENSE-APACHE-2.0, matches it as Apache-2.0, and detection succeeds.

Proposed Solution

Rename the license files to match the pattern that vis-network already uses (and that licensee recognizes):

git mv LICENSE.md LICENSE               # or simply delete it
git mv LICENSE.Apache-2.0.txt LICENSE-APACHE-2.0
git mv LICENSE.MIT.txt LICENSE-MIT

This way:

  • licensee finds and matches LICENSE-APACHE-2.0 (full license text)
  • package.json already has "license": "(Apache-2.0 OR MIT)" — npm/SPDX detection is fine
  • It also makes the license file layout consistent with vis-network

Alternatively, the LICENSE.md wrapper could be replaced with one of the full license texts (e.g. copy LICENSE.MIT.txt to LICENSE) while keeping the other as a separate file.


More details on how GitHub license detection works

GitHub uses licensee, which:

  1. Looks for files matching common license filenames: LICENSE, LICENSE.md, LICENSE.txt, LICENCE, COPYING, etc.
  2. Reads the content of the first match
  3. Fuzzy-matches it against a corpus of known SPDX license texts
  4. If similarity is above a threshold (~90%), it identifies the license

The current LICENSE.md is a ~200-byte markdown file with links. The shortest known license template (MIT) is ~1000 bytes. The content similarity is far too low for any match, resulting in NOASSERTION.

licensee also recognizes files named LICENSE-* as additional license files, which is why vis-network's LICENSE-APACHE-2.0 works — it's both a valid license filename pattern and contains the full license text.


Reusable guide & diagnostic script: GitHub License Detection NOASSERTION — Diagnosis Guide & Script
Contains a detailed explanation of how licensee works, common failure patterns, and a shell script (check-github-license-detection.sh) to diagnose license detection issues on any GitHub repository.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions