Skip to content

Host should not return a redirect source file from getSourceFile #22524

Closed
@JonWallsten

Description

@JonWallsten

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

When using webpack-dev-server in --watch mode and you make a change the build process throws the following error:

ERROR in Error: Debug Failure. False expression: Host should not return a redirect source file from `getSourceFile`
    at tryReuseStructureFromOldProgram (C:\Users\me\repo\web-app-angular\node_modules\typescript\lib\typescript.js:74285:26)
    at Object.createProgram (C:\Users\me\repo\web-app-angular\node_modules\typescript\lib\typescript.js:73988:34)
    at AngularCompilerProgram._updateProgramWithTypeCheckStubs (C:\Users\me\repo\web-app-angular\packages\compiler-cli\src\transformers\program.ts:508:26)
    at C:\Users\me\repo\web-app-angular\packages\compiler-cli\src\transformers\program.ts:187:18
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

Expected behavior

It should not throw an error and compile the code as usual.

Minimal reproduction of the problem with instructions

See this PR for more info: ng-packagr/ng-packagr#637

What is the motivation / use case for changing the behavior?

Webback watch mode is useless if you have to restart it after each change.

Environment


Angular version: 5.2.6 | 6.0.0-beta.6

 
For Tooling issues:
- Node version: 8.9.4
- Platform:  Windows

Others:

Typescript: 2.6.2
Webpack: 4.0.1
Webpack-dev-server: 3.1.0

Conclusion

This seems to work. Not sure what else it will break though.
Added the redirectInfo fix from the PR i referenced.

// program.js:485 (compiled file)
tmpProgram.getSourceFiles().forEach(function (sf) {
    if (_this.hostAdapter.isSourceFile(sf.fileName)) {
        if (sf['redirectInfo']) {
            sf = sf['redirectInfo'].redirectTarget;
        }
        sourceFiles.push(sf.fileName);
    }
    if (util_1.TS.test(sf.fileName) && !util_1.DTS.test(sf.fileName)) {
        tsFiles.push(sf.fileName);
    }
});
// program.ts:568 (source file)
// note: redirectInfo does not exists on ts.SourceFile hence the any.
tmpProgram.getSourceFiles().forEach(sf => {
  if (this.hostAdapter.isSourceFile(sf.fileName)) {
      if ((sf as any)['redirectInfo']) {
          sf = (sf as any)['redirectInfo'].redirectTarget;
      }
    sourceFiles.push(sf.fileName);
  }
  if (TS.test(sf.fileName) && !DTS.test(sf.fileName)) {
    tsFiles.push(sf.fileName);
  }
});
console.log(sf.fileName);
console.log(sf['redirectInfo'].redirectTarget.fileName);
--------------------------
C:/Users/me/repo/web-app-angular/node_modules/@types/webpack/node_modules/source-map/source-map.d.ts
C:/Users/me/repo/web-app-angular/node_modules/@types/uglify-js/node_modules/source-map/source-map.d.ts
--------------------------

Edit: It seems like my ticket is not clear enough in pointing out the issue based on the new posts in this thread.
The issue happens due to identical *.d.ts file found via two paths in the compilation.
In plain english: The packages uses the same dependency that includes a definition file.

Activity

added this to the needsTriage milestone on Mar 1, 2018
DcsMarcRemolt

DcsMarcRemolt commented on Mar 2, 2018

@DcsMarcRemolt

This is actually not a new problem, see angular/angular-cli/issues/8332

Wish they would have taken it seriously back then, now we have the mess as TS 2.6 is supported.

devoto13

devoto13 commented on Mar 2, 2018

@devoto13
Contributor

Here is another reproduction using Angular CLI with linked dependencies and preliminary investigation of the problem:

I think it is a bug in compiler-cli. Error message says that getSourceFile() should not return redirect file. And the implementation in TypeScript CompilerHost never does it, however CompilerHost implemented in Angular compiler-cli caches SourceFiles from old program in internal cache and returns them from the method. And cached files can be redirect files, which hits the assertion when creating a new program.

modified the milestones: needsTriage, Backlog on Mar 29, 2018
kspearrin

kspearrin commented on Apr 7, 2018

@kspearrin

Same problem here using Typescript 2.6.2, webpack 3.10, Angular 5.2.x with ngtools/webpack 1.10.2 (compiler-cli 5.2). Interestingly, the problem only seemed to start for me after converting my webpack config to typescript. Reverting it back to JavaScript resolves the problem.

JonWallsten

JonWallsten commented on Apr 7, 2018

@JonWallsten
ContributorAuthor

@kspearrin It's because the issue, at least in my case, is duplicate typings for UglifyJS, which is included in webpack. If you have the config in JS it won't use typings hence no error. Good to know though, it's not super important for us to have the config in TS.

kspearrin

kspearrin commented on Apr 7, 2018

@kspearrin

Yes I think it was something to do with the typings that were added for that conversion. See here for the commit that broke things: bitwarden/clients@df4e7f0

DcsMarcRemolt

DcsMarcRemolt commented on Apr 13, 2018

@DcsMarcRemolt

Changing the webpack configs to JS was not sufficient in my case. But as soon as I removed the [at]types/webpack and [at]types/webpack-merge packages from my project the bug disappeared. Finally a current TS version for my projects!

samelliottdlt

samelliottdlt commented on Apr 18, 2018

@samelliottdlt

I was able to solve this issue by disabling AOT in ngtools/webpack 1.10.2 by setting the skipCodeGeneration option to true.

new AngularCompilerPlugin({
  ...options,
  skipCodeGeneration: true
})
charlieargue

charlieargue commented on Apr 18, 2018

@charlieargue

Hi @samelliottdlt (et all), I'm confused by your ngtools/webpack version, you said:

ngtools/webpack 1.10.2

I have:

...
  "devDependencies": {
    "@ngtools/webpack": "^6.0.0-rc.3",
...

Am I on the wrong version??? Just wondering...

Either way, I keep getting the same error (and none of the above workarounds/fixes have helped):

ERROR in Debug Failure. False expression: Host should not return a redirect source file from `getSourceFile`

node --version && npm --version

  • v8.11.1
  • 5.8.0

package.json

{
    ...
  "scripts": {
    "start": "rimraf dist && webpack-dev-server --progress --info --config config/webpack.localhost.ts --hot --watch=false --hot-only --bail --profile  --open",
    ...
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "dependencies": {
    "@angular/animations": "^5.2.5",
    "@angular/common": "^5.2.5",
    "@angular/compiler": "^5.2.5",
    "@angular/core": "^5.2.5",
    "@angular/forms": "^5.2.5",
    "@angular/http": "^5.2.5",
    "@angular/platform-browser": "^5.2.5",
    "@angular/platform-browser-dynamic": "^5.2.5",
    "@angular/router": "^5.2.5",
    "@ng-bootstrap/ng-bootstrap": "1.1.1",
    "@types/angular": "^1.6.43",
    "@types/lodash": "4.14.106",
    "@types/socket.io-client": "1.4.32",
    "angular-confirmation-popover": "4.1.0",
    "angular2-json2csv": "1.1.2",
    "angular2-moment": "1.8.0",
    "angular2-template-loader": "0.6.2",
    "angular2-toaster": "5.0.1",
    "angular2-uuid": "1.1.1",
    "animate.css": "3.6.1",
    "bootstrap": "4.0.0",
    "core-js": "^2.5.3",
    "font-awesome": "4.7.0",
    "glyphicons-halflings": "1.9.1",
    "hammerjs": "2.0.8",
    "http-server": "0.11.1",
    "lodash": "4.17.5",
    "moment": "2.22.0",
    "ng2-file-upload": "1.3.0",
    "ng2-img-cropper": "0.9.0",
    "ng2-scroll-to": "1.0.7",
    "ng2-slim-loading-bar": "4.0.0",
    "node-sass": "4.8.3",
    "raven-js": "3.24.1",
    "reflect-metadata": "0.1.12",
    "rxjs": "^5.5.9",
    "socket.io-client": "2.1.0",
    "typescript": "2.8.1",
    "typings": "2.1.1",
    "zone.js": "^0.8.20"
  },
  "devDependencies": {
    "@angular/compiler-cli": "^5.2.5",
    "@ngtools/webpack": "^6.0.0-rc.3",
    "@types/angular": "^1.6.42",
    "@types/chai": "4.1.2",
    "@types/core-js": "^0.9.46",
    "@types/hammerjs": "2.0.35",
    "@types/node": "^9.4.6",
    "@types/rx": "^4.1.1",
    "@types/socket.io-client": "1.4.32",
    "@types/webpack": "^4.1.3",
    "angular2-template-loader": "0.6.2",
    "awesome-typescript-loader": "5.0.0",
    "copy-webpack-plugin": "^4.5.1",
    "css-loader": "^0.28.11",
    "extract-text-webpack-plugin": "4.0.0-beta.0",
    "file-loader": "^1.1.11",
    "html-loader": "0.5.5",
    "html-webpack-plugin": "3.0.7",
    "jasmine-core": "3.1.0",
    "jasmine-spec-reporter": "4.2.1",
    "karma": "2.0.0",
    "karma-chrome-launcher": "2.2.0",
    "karma-jasmine": "1.1.1",
    "karma-phantomjs-launcher": "1.0.4",
    "karma-sourcemap-loader": "0.3.7",
    "karma-verbose-reporter": "0.0.6",
    "karma-webpack": "3.0.0",
    "live-server": "^1.2.0",
    "lodash": "4.17.5",
    "moment": "2.22.0",
    "ngc-webpack": "^4.1.2",
    "node-sass": "^4.8.3",
    "null-loader": "0.1.1",
    "phantomjs-prebuilt": "2.1.16",
    "protractor": "5.3.1",
    "raw-loader": "^0.5.1",
    "request": "2.85.0",
    "rimraf": "^2.6.2",
    "sass-loader": "^6.0.7",
    "style-loader": "^0.20.3",
    "supertest": "3.0.0",
    "to-string-loader": "^1.1.5",
    "ts-loader": "^4.0.0-beta.0",
    "ts-node": "^5.0.1",
    "tslint": "^5.9.1",
    "tslint-loader": "^3.6.0",
    "typescript": "^2.8.1",
    "typings": "2.1.1",
    "url-loader": "1.0.1",
    "webpack": "^4.6.0",
    "webpack-bundle-analyzer": "^2.11.1",
    "webpack-cli": "^2.0.14",
    "webpack-dev-server": "3.1.3",
    "webpack-merge": "^4.1.2",
    "write-file-webpack-plugin": "4.2.0"
  },
  "repository": {}
}

webpack.common.ts

// --- --- --- --- --- --- --- --- --- --- 
// USED by ALL 3 environment webpack configs
// --- --- --- --- --- --- --- --- --- --- 
const webpack = require('webpack');
const ngcWebpack = require('ngc-webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const pathPublicFolder = 'assets';
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const REGEX_IMAGE_TEST = /\.(png|jpe?g|gif|ico)$/;
const REGEX_FONT_TEST = /\.(woff|woff2|ttf|eot|svg)(\?.*$|$)/;

console.log('\u2592\u2592 (webpack.COMMON.js) ... ');
export const commonConfig = {
    entry: {
        app: './src/main.ts',
        polyfills: './src/polyfills.ts',
        vendor: './src/vendor.ts',
    },
    target: 'web',
    optimization: {
        splitChunks: {
            cacheGroups: {
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendor',
                    chunks: 'initial',
                    enforce: true
                }
            }
        }
    },
    resolve: {
        extensions: ['.js', '.ts', '.html']
    },
    module: {
        rules: [
            {
                test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
                use: ['@ngtools/webpack']
            },
            {
                test: /.js$/,
                parser: {
                    system: true
                }
            },
            // Typescript
            {
                test: /\.ts$/,
                exclude: /node_modules/,
                include: path.resolve(__dirname, 'src'),
                use: '@ngtools/webpack'
            },
            // Templates
            {
                test: /\.html$/,
                exclude: /index.html$/i,
                use: [
                    {
                        loader: 'raw-loader'
                    }
                ]
            },
            {
                test: REGEX_IMAGE_TEST,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: pathPublicFolder + '[name].[hash].[ext]'
                        }
                    }
                ]
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.scss$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: [
                        {
                            loader: 'css-loader',
                            options: {
                                // If you are having trouble with urls not resolving add this setting.
                                // See https://github.com/webpack-contrib/css-loader#url
                                url: false,
                                minimize: true,
                                sourceMap: true
                            }
                        },
                        {
                            loader: 'sass-loader',
                            options: {
                                sourceMap: true
                            }
                        }
                    ]
                })
            },
            {
                test: REGEX_FONT_TEST,
                use: [
                    'file-loader'
                ]
            }
            // TURNED OFF LINTING FOR NOW
            // {
            //     test: /\.ts$/,
            //     enforce: 'pre',
            //     loader: 'tslint-loader',
            //     options: { /* Loader options go here */ }
            // }
        ]
    },
    plugins: [
        new ExtractTextPlugin('[name].css'), // huh? why here?

        // decomish this, since ACPlugin? (see localhost)
        new ngcWebpack.NgcWebpackPlugin({
            AOT: true,
            tsConfigPath: './tsconfig.json',
            mainPath: './src/main.ts'
        }),
        new CopyWebpackPlugin([
            {
                from: './src/assets/images',
                to: './assets/images',
                test: REGEX_IMAGE_TEST,
                toType: 'dir'
            },
            {
                // the font-awesome fonts
                from: './src/assets/fonts/font-awesome',
                to: './assets/fonts',
                test: REGEX_FONT_TEST,
                toType: 'dir'
            },
            {
                // the google fonts (open sans) one dir higher, sorry... I blame sing and bootstrap and webpack 4 :)
                from: './src/assets/fonts',
                to: './assets/fonts',
                test: REGEX_FONT_TEST,
                toType: 'dir'
            },
        ]),
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin(),

        new HtmlWebpackPlugin({
            template: 'src/index.html',
            favicon: './src/assets/images/favicon.ico',
            title: 'Alpha Omega TODO: change me'
        }),
    ],
};

webpack.localhost.ts

// --- --- --- --- --- --- --- --- --- --- 
// USED for `npm start` 
// serving from local webpack dev server, from root dir webpack.config.js
// --- --- --- --- --- --- --- --- --- --- 
console.log('\u2592\u2592 (webpack.LOCALHOST.ts) WEBPACK NODE_ENV: ' + process.env.NODE_ENV);
import { commonConfig } from './webpack.common';
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const WriteFilePlugin = require('write-file-webpack-plugin');
var moment = require('moment'); // NOTE: keep var, errors as const
const apiHost = "'http://localhost:4000'";
const socketioHost = "'http://localhost:4000'";
const sentryIOConfig = "'https://d9e0c116cbda4f028b8933a6715ceb65@sentry.io/330255'";
const friendlyDate = moment().format("dddd, MMMM Do YYYY, h:mm:ss a");
const path = require('path');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin;

// This helper function is not strictly necessary.
// I just don't like repeating the path.join a dozen times.
function srcPath(subdir) {
    return path.join(__dirname, '..', subdir);
}

// --- --- --- --- --- --- --- --- --- --- 
module.exports = webpackMerge(commonConfig, {
    mode: 'development',
    devtool: process.env.NODE_ENV === 'production' ? false : 'source-map',
    devServer: {
        hot: true,
        historyApiFallback: true,
        stats: 'minimal',
        port: 8080,
        host: 'localhost',
        https: false
    },
    output: {
        path: path.resolve(__dirname, '../dist'),
        publicPath: '',
        filename: '[name].[hash].js',
        /* will be polyfill, vendor, or app.js */
        chunkFilename: '[id].[hash].chunk.js'
    },
    plugins: [
        // localhost
        new webpack.DefinePlugin({
            'process.env': {
                'ENV': JSON.stringify(process.env.NODE_ENV)
            },
            __API__: apiHost,
            __APPVERSION__: JSON.stringify(friendlyDate),
            __SOCKETIO__: socketioHost,
            __SENTRYIOCONFIG__: sentryIOConfig
        }),
        new WriteFilePlugin(),
        // new BundleAnalyzerPlugin(),
        // NOTE: needed for ERROR: 
        // thx: https://github.com/angular/angular/issues/22524#issuecomment-382471279 (a record, fix used 4 hours after posted :)
        // new AngularCompilerPlugin({
        //     // WORKS: (but diff. plugins):
        //     // tsConfigPath: './tsconfig.json',
        //     // mainPath: './src/main.ts'

        //     // DOESN'T WORK:
        //     tsConfigPath: srcPath('tsconfig.json'),
        //     entryModule: srcPath('/src/app/app.module.ts#AppModule'), 
        //     sourceMap: true,
        //     skipCodeGeneration: true
        // })
    ],
});

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": true,
    "noImplicitAny": false,
    "suppressImplicitAnyIndexErrors": true,
    "lib": [
      "dom",
      "es2016",
      "es2017"
    ],
    "baseUrl": ".",
    "typeRoots": [
      "node_modules/@types"
    ],
    "types": [
      "hammerjs",
      "socket.io-client",
      "webpack"
    ],
    "skipLibCheck": true
  },
  "exclude": [
    "node_modules",
    "dist-development",
    "dist-production",
    "dist",
    "typings"
  ],
  "angularCompilerOptions": {
    "debug": true
  }
}

Thanks so much!

63 remaining items

added a commit that references this issue on Jul 9, 2019
9bd0e96
dtychshenko

dtychshenko commented on Jul 11, 2019

@dtychshenko

Thanks to this great pointer from @DcsMarcRemolt, I was able to find our offending code that lead to this error.

In node_modules/typescript/lib/typescript.js, I changed line:

ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`")

to:

 ts.Debug.assert(
    !newSourceFile.redirectInfo, 
    "Host should not return a redirect source file from `getSourceFile`", 
    () => `Duplicate .d.ts files: ${newSourceFile.fileName} <-> ${newSourceFile.redirectInfo.redirectTarget.fileName}`
);

And then got the error like:

ERROR in Debug Failure. False expression: Host should not return a redirect source file from `getSourceFile`
Verbose Debug Information: Duplicate .d.ts files: C:/<...>/node_modules/ngx-bootstrap/Typeahead/ngx-bootstrap-typeahead.d.ts <-> C:/<...>/node_modules/ngx-bootstrap/typeahead/ngx-bootstrap-typeahead.d.ts

Which I found odd, so I searched our code base for: /Typeahead with a case-sensitive flag, and, lo and behold, someone added an import like import { TypeaheadMatch } from 'ngx-bootstrap/Typeahead';. After fixing the letter casing, the error was gone.

A bit unfortunate that such a small typo can cause such an obscure error that lead to hours of debugging, but, oh well... it happens. Hope this helps someone else!

JonWallsten

JonWallsten commented on Jul 12, 2019

@JonWallsten
ContributorAuthor

Just wanted to let you know that the PR for this issue is done. We're waiting for the code owner to be back and then approve. So hopefully in a short time we just leave this thread behind us!

added a commit that references this issue on Jul 15, 2019
13dbb98
jmccarrell-lmi

jmccarrell-lmi commented on Aug 21, 2019

@jmccarrell-lmi

So... this was only released for Angular 8? So anyone on Angular 7, which was released less than a year ago is SOL?

EDIT: I just realized my project is on Angular 6, so a more productive question from me would be, will this fix be present in 6? Or any other older versions of Angular?

Bjeaurn

Bjeaurn commented on Aug 21, 2019

@Bjeaurn

Well, why can’t you upgrade?

jmccarrell-lmi

jmccarrell-lmi commented on Aug 21, 2019

@jmccarrell-lmi

tens of thousands of lines of code and it isn't even my project, im like a guest in the project (but i heavily need the project to work effectively for my own sister project).

Bjeaurn

Bjeaurn commented on Aug 21, 2019

@Bjeaurn

Upgrading from v6 or 7 is nearly automatic. Maybe a day of compile errors to fix. Worth it imo.

DanielSchaffer

DanielSchaffer commented on Aug 21, 2019

@DanielSchaffer

@Bjeaurn Look at Mr Fancypants over here with the spare day to spend fixing compile errors for a framework upgrade! ;)

Bjeaurn

Bjeaurn commented on Aug 21, 2019

@Bjeaurn

Short answer to your initial question: no. No backwards updates. The timeline clearly says we move forward. Breaking changes every major, etc. Basic semver.

If you’re stuck in v6 and you can’t upgrade “cause a day”, I really feel for you and your team. Someone needs to tell management or the PO that this will save you days when 9 comes out. Or weeks when 10 comes out.

GL HF. Let me know if you want external help, I’ll be happy to accommodate you.

added a commit that references this issue on Sep 6, 2019
8407e6c
Rosseyn

Rosseyn commented on Sep 12, 2019

@Rosseyn

Nothing to add as the issue has already been fixed in later update, but I've found a reliable work-around for my situation, and perhaps others that aren't able to upgrade at the moment, to at least keep the webpack dev server watching:

  • ng serve
  • Save a *.ts file to trigger compile
  • Get error
  • Save the same *.ts file to recompile again
  • Error should go away and you can resume compiling as usual until the next time you ng serve

If you save anything other than a *.ts file first, you'll end up in an unrecoverable compiler state until you ng serve again. You don't need to save *.ts file twice each time, just immediately after you ng serve.

You should end up with a sequence similar to this:

Date: 2019-09-12T23:17:33.177Z - Hash: xxx - Time: 23148ms
** Angular Live Development Server is listening on localhost:4201, open your browser on http://localhost:4201/ **
ℹ 「wdm」: Compiled successfully.
ℹ 「wdm」: Compiling...

Date: 2019-09-12T23:20:02.348Z - Hash: xxx
20 unchanged chunks

Time: 1206ms

ERROR in Debug Failure. False expression: Host should not return a redirect source file from `getSourceFile`
ℹ 「wdm」: Failed to compile.
ℹ 「wdm」: Compiling...

Date: 2019-09-12T23:20:16.199Z - Hash: xxx
19 unchanged chunks
chunk {main} main.js, main.js.map (main) 1.68 MB [initial] [rendered]
Time: 11187ms
ℹ 「wdm」: Compiled successfully.
angular-automatic-lock-bot

angular-automatic-lock-bot commented on Oct 13, 2019

@angular-automatic-lock-bot

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

locked and limited conversation to collaborators on Oct 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @alexeagle@mhevery@Rosseyn@DanielSchaffer@piernik

        Issue actions

          Host should not return a redirect source file from `getSourceFile` · Issue #22524 · angular/angular