Skip to content

[macOS] Plugin fails to load in IDE due to unsigned AOT binary #332

Description

@solid-illiaaihistov

📌 Problem Description
When using solid_lints from the master branch (which has been migrated to the new analysis_server_plugin API) on macOS (Apple Silicon / arm64), custom lint rules are not highlighted in the IDE (VS Code), while built-in Dart lint rules continue to work correctly.

Technical Details (Root Cause):
Upon loading the plugin, the Dart Analysis Server compiles it into an AOT snapshot file: ~/.dartServer/.plugin_manager//bin/plugin.aot.
The built-in Dart compiler generates this binary with a temporary linker-signed code signature (flags=0x20002).
Recent versions of macOS forbid dynamic loading (dlopen) of binaries with the linker-signed flag into Hardened Runtime processes due to system security policies.
Consequently, the operating system silently terminates the plugin process with a SIGKILL signal (Code Signature Invalid). The Analysis Server ignores the failure and proceeds without executing custom solid_lints rules.
This issue is tracked upstream in the Dart SDK repository: Dart SDK Issue #63813.

🧪 Steps to Reproduce
Open a project on a macOS (arm64 / M1–M4) machine.

Add the solid_lints dependency to pubspec.yaml, explicitly referencing the master branch (without using a local path:):

dev_dependencies:
  solid_lints:
    git:
      url: https://github.com/solid-software/solid_lints.git
      ref: master

📌 Note: You must specify a Git dependency (ref: master). When using a local path: ../solid_lints, the analyzer executes the plugin in source mode, preventing the bug from reproducing on the plugin developer's local machine.

Enable the plugin in analysis_options.yaml (ensure no commented-out local path: entries remain):

plugins:
  solid_lints:

Write code containing an intentional rule violation (for example, missing blank line before a return statement).

Actual Result: solid_lints errors are not highlighted in the editor. Running dart analyze or checking server diagnostics reports "No known analysis plugins".

Expected Result: solid_lints rules should highlight errors and provide quick fixes.

🛠 Workaround
To resolve the issue, the generated AOT files must be re-signed using the native macOS codesign utility. This changes the code signature flag from linker-signed to a clean adhoc signature (flags=0x2).

  1. Create the solid_lints:setup CLI Script
    Add a bin/setup.dart file to the solid_lints package:
import 'dart:io';
void main() async {
  if (!Platform.isMacOS) {
    print('✅ Setup skipped: Not on macOS.');
    return;
  }
  final home = Platform.environment['HOME'];
  if (home == null) return;
  final pluginDir = Directory('$home/.dartServer/.plugin_manager');
  if (!await pluginDir.exists()) {
    print('⚠️ Plugin manager cache directory not found. Please open VS Code first.');
    return;
  }
  final aotFiles = await pluginDir
      .list(recursive: true)
      .where((entity) => entity is File && entity.path.endsWith('plugin.aot'))
      .toList();
  if (aotFiles.isEmpty) {
    print('⚠️ No plugin.aot files found. Make sure VS Code has analyzed the project.');
    return;
  }
  print('🔒 Signing ${aotFiles.length} AOT plugin snapshot(s) for macOS...');
  for (final file in aotFiles) {
    final result = await Process.run('codesign', [
      '--force',
      '--deep',
      '--sign',
      '-',
      file.path,
    ]);
    if (result.exitCode == 0) {
      print('✅ Signed: ${file.path}');
    } else {
      print('❌ Failed to sign ${file.path}: ${result.stderr}');
    }
  }
  print('\n🎉 Done! Please restart Analysis Server in VS Code (Cmd+Shift+P -> Dart: Restart Analysis Server).');
}
  1. Execution by Developer
    After opening the project in the IDE, the developer runs the following command in the terminal:
dart run solid_lints:setup

After executing this command and restarting the Dart Analysis Server (Cmd+Shift+P -> Dart: Restart Analysis Server in VS Code), all solid_lints rules begin working and properly highlight errors in the IDE.

⚠️ Important Nuances and Limitations
Re-execution Required Upon Recompilation: The script signs existing, pre-compiled files. If a developer:

Updates the Dart / Flutter SDK version;
Clears the analyzer cache (~/.dartServer);
Updates the solid_lints package version;
The Dart Analysis Server will recompile a new plugin.aot with the linker-signed flag, requiring dart run solid_lints:setup to be executed again.

Manual Step After First Project Launch: The script can only be run after the project has been opened in the IDE at least once (so that the Analysis Server generates the .plugin_manager directory and the plugin.aot binary in the background).

Inability to Auto-run via Pub: Dart/Pub intentionally omits post-install lifecycle hooks for security reasons. Consequently, this script cannot be executed automatically during pub get. Developers looking for automation can add a VS Code task (.vscode/tasks.json with runOn: folderOpen) or configure Git hooks.

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