Fixing a VS Code Extension for PHPCS 4.x — Together

A PHP_CodeSniffer update broke our linting. So we dug into the extension source, traced the failures, and patched it — human and AI, side by side.

Today I ran into one of those problems that feels small at first — my VS Code linting just stopped working. PHP_CodeSniffer had updated to 4.x, and the vscode-php-codesniffer extension I rely on was throwing fatal errors. No warnings, no squiggly lines, just silence.

So I did what I do now — I opened Claude Code and said, essentially: help me figure out what broke.

The Investigation

The extension bundles its own PHP integration files that act as a custom PHPCS report. These files extend internal PHPCS classes — and PHPCS 4.x changed the API underneath them. We needed to find exactly what broke and why.

Claude dove into the extension source at assets/phpcs-integration/, cross-referencing the bundled PHP files against the PHPCS 4.x changelog and source code. Within minutes, we had a clear picture of three breaking changes — two critical, one cosmetic.

What Broke

1. The tokenizerType property was removed

PHPCS 4.x dropped support for JavaScript and CSS tokenizers entirely — only PHP remains. The extension’s File.php constructor was copying $phpcsFile->tokenizerType, a property that no longer exists. Fatal error.

2. The fixableCount property was split

What used to be a single $fixableCount property was refactored into $fixableErrorCount and $fixableWarningCount. The constructor was copying a ghost. Another fatal error.

3. The MySource standard was removed

The extension’s package.json still listed MySource as a selectable coding standard, but PHPCS 4.x removed it entirely. Not a crash, but a confusing dead end for anyone who selected it.

What Didn’t Break (and Why That Matters)

This is the part I found most interesting about working with Claude on this. We didn’t just find what was broken — we systematically verified what wasn’t. PHPCS 4.x added parameter type declarations to several method signatures, which could have been a problem for the extension’s untyped overrides. But PHP 7.2+ allows omitting parameter types in child classes (contravariant widening), so those overrides were safe.

We also confirmed that the report data structure, the Fixer class properties, exit code handling, and runtime-set arguments all remained compatible. Having that confidence — knowing what we didn’t need to touch — was just as valuable as finding the bugs.

The Fix

The solution was straightforward once we understood the landscape. We used property_exists() checks to maintain backward compatibility with PHPCS 3.x while supporting 4.x:

// tokenizerType was removed in PHPCS 4.x (only PHP tokenizer remains)
if (property_exists($phpcsFile, 'tokenizerType')) {
    $this->tokenizerType = $phpcsFile->tokenizerType;
}

// fixableCount was split into fixableErrorCount + fixableWarningCount in PHPCS 4.x
if (property_exists($this, 'fixableCount')) {
    $this->fixableCount = $phpcsFile->fixableCount;
} else {
    $this->fixableErrorCount = $phpcsFile->fixableErrorCount;
    $this->fixableWarningCount = $phpcsFile->fixableWarningCount;
}

Simple. Defensive. Works with both versions. We also removed MySource from the extension’s settings enum.

The Collaboration Pattern

What struck me about this session was how naturally it flowed. I brought the context — I knew my linting was broken and roughly where to look. Claude brought the thoroughness — methodically reading source files, cross-referencing PHPCS changelogs, and building a complete compatibility matrix before we touched a single line of code.

The plan Claude produced wasn’t just “here’s the fix.” It was a full analysis: what broke, what didn’t break, why the safe things were safe, and what specifically to change. That kind of systematic verification is exactly the work that’s easy to skip when you’re debugging alone — and exactly the work that prevents you from introducing new bugs.

This is what I mean when I talk about human-AI collaboration. Not “AI writes my code.” More like: I steer, Claude investigates, we decide together, and the result is better than either of us would produce alone.


We contributed our fixes back upstream to the extension maintainer. If you use vscode-php-codesniffer and have upgraded to PHPCS 4.x, this one’s for you.

Fixes phpcs 4.x compatibility Pull Request

Our upstream contribution to ObliviousHarmony/vscode-php-codesniffer — adding property_exists() guards for removed PHPCS 4.x properties and cleaning up the deprecated MySource standard.

View on GitHub

Update (March 7, 2026): The pull request was accepted and merged by the extension maintainer. Our fix will be included in an upcoming release of vscode-php-codesniffer — so if you’re hitting this issue, relief is on the way.